home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / RCS / pdev.c,v < prev    next >
Text File  |  1990-06-27  |  87KB  |  3,211 lines

  1. head     1.15;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.15
  10. date     90.06.27.11.17.12;  author shirriff;  state Exp;
  11. branches ;
  12. next     1.14;
  13.  
  14. 1.14
  15. date     90.06.25.17.44.47;  author douglis;  state Exp;
  16. branches ;
  17. next     1.13;
  18.  
  19. 1.13
  20. date     90.05.01.10.19.26;  author brent;  state Exp;
  21. branches ;
  22. next     1.12;
  23.  
  24. 1.12
  25. date     90.02.19.14.44.37;  author douglis;  state Exp;
  26. branches ;
  27. next     1.11;
  28.  
  29. 1.11
  30. date     90.01.31.08.23.53;  author ouster;  state Exp;
  31. branches ;
  32. next     1.10;
  33.  
  34. 1.10
  35. date     89.09.12.14.42.55;  author brent;  state Exp;
  36. branches ;
  37. next     1.9;
  38.  
  39. 1.9
  40. date     89.06.02.13.38.23;  author brent;  state Exp;
  41. branches ;
  42. next     1.8;
  43.  
  44. 1.8
  45. date     89.04.12.13.33.01;  author ouster;  state Exp;
  46. branches ;
  47. next     1.7;
  48.  
  49. 1.7
  50. date     89.03.20.15.52.26;  author ouster;  state Exp;
  51. branches ;
  52. next     1.6;
  53.  
  54. 1.6
  55. date     89.01.26.10.12.54;  author brent;  state Exp;
  56. branches ;
  57. next     1.5;
  58.  
  59. 1.5
  60. date     89.01.06.07.59.52;  author brent;  state Exp;
  61. branches ;
  62. next     1.4;
  63.  
  64. 1.4
  65. date     88.11.11.11.30.10;  author brent;  state Exp;
  66. branches ;
  67. next     1.3;
  68.  
  69. 1.3
  70. date     88.10.18.13.35.23;  author brent;  state Exp;
  71. branches ;
  72. next     1.2;
  73.  
  74. 1.2
  75. date     88.08.29.13.00.07;  author brent;  state Exp;
  76. branches ;
  77. next     1.1;
  78.  
  79. 1.1
  80. date     88.08.26.16.12.17;  author brent;  state Exp;
  81. branches ;
  82. next     ;
  83.  
  84.  
  85. desc
  86. @Library for pseudo-device servers
  87. @
  88.  
  89.  
  90. 1.15
  91. log
  92. @Fixed inconsistencies in default handlers.
  93. @
  94. text
  95. @/* 
  96.  * pdev.c --
  97.  *
  98.  *    The routines in this module set up a call-back interface for
  99.  *    a pseudo-device server.  Pdev_Open creates a pseudo-device and
  100.  *    installs service procedures.  These service procedures are called
  101.  *    when client processes use the pseudo-device.  The harness procedure
  102.  *    which invokes the call-backs takes care of the kernel interface.
  103.  *    There are also default service procedures so the user of Pdev_Open
  104.  *    need only provide service procedures for the operations of interest.
  105.  *
  106.  * Copyright 1989 Regents of the University of California
  107.  * Permission to use, copy, modify, and distribute this
  108.  * software and its documentation for any purpose and without
  109.  * fee is hereby granted, provided that the above copyright
  110.  * notice appear in all copies.  The University of California
  111.  * makes no representations about the suitability of this
  112.  * software for any purpose.  It is provided "as is" without
  113.  * express or implied warranty.
  114.  */
  115.  
  116. #ifndef lint
  117. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.14 90/06/25 17:44:47 douglis Exp Locker: shirriff $ SPRITE (Berkeley)";
  118. #endif not lint
  119.  
  120. #include <stdio.h>
  121. #include <sprite.h>
  122. #include <ctype.h>
  123. #include <errno.h>
  124. #include <pdev.h>
  125. #include <list.h>
  126. #include <status.h>
  127. #include <stdlib.h>
  128. #include <string.h>
  129. #include <sys/file.h>
  130.  
  131. /*
  132.  * The string below holds an error message if Pdev_Open fails.
  133.  */
  134.  
  135. char pdev_ErrorMsg[150];
  136.  
  137. /*
  138.  * Boolean that can be toggled by applications to get tracing.
  139.  */
  140. int pdev_Trace;
  141.  
  142. /*
  143.  * The Pdev structure is the top-level state for the pseudo-device
  144.  * or pseudo-filelsystem server.  The state for each pseudo-device connection
  145.  * is hung in a list off of this.  This also has a set of default service
  146.  * procedures for the various pseudo-device operations.  Two
  147.  * fields of the Pdev struct are made available to the client of the
  148.  * Pdev package so it can do IOControls on the service stream and
  149.  * set a private data pointer.
  150.  */
  151.  
  152. typedef struct Pdev {
  153.     Pdev_Stream stream;        /* Type PDEV_MAGIC */
  154.     List_Links connectList;    /* List of all service streams for this
  155.                  * pseudo-device (pseudo-filesystem). */
  156.     int requestBufSize;        /* Default request buffer size */
  157.     int readBufSize;        /* Size for optional read buffer */
  158.     Pdev_CallBacks *defaultService;/* Default handlers for pdev operations */
  159. } Pdev;
  160.  
  161. /*
  162.  * The structure below corresponds to a pseudo-device connection between
  163.  * a client and the server.
  164.  */
  165.  
  166. typedef struct ServiceStream {
  167.     Pdev_Stream stream;        /* Type PDEV_STREAM_MAGIC */
  168.     List_Links links;        /* pdev streams are linked into a
  169.                  * list of all streams for the same
  170.                  * pseudo-device (pseudo-file-system). */
  171.     Address parent;        /* Pdev state with which this stream is
  172.                  * associated. */
  173.     int streamID;        /* Sprite identifier for request stream. */
  174.     Address requestBuf;        /* A buffer for requests and data from the
  175.                  * client */
  176.     Address readBuf;        /* A buffer for data to be read over the
  177.                  * pseudo-device by the application. This
  178.                  * is allocated by us and passed to the
  179.                  * read call-back. If read buffering is set
  180.                  * then we allocate this at open-time and
  181.                  * pass it off to the open call-back. */
  182.     int readBufSize;        /* Size of the readBuf. */
  183.     Address ioctlOutBuf;    /* Buffer for results of ioctl */
  184.     int ioctlBufSize;        /* Size of ioctlOutBut */
  185.     Pdev_CallBacks *service;    /* Set of procedures to handle the various
  186.                  * pseudo-device operations. */
  187. } ServiceStream;
  188.  
  189. #define LIST_TO_SRVPTR(listPtr) \
  190.     (ServiceStream *)((int)(listPtr) - sizeof(Pdev_Stream))
  191.  
  192. static int    PdevDefaultOpen();
  193. static int    PdevDefaultRead();
  194. static int    PdevDefaultWrite();
  195. static int    PdevDefaultIoctl();
  196. static int    PdevDefaultClose();
  197. static int    PdevDefaultGetAttr();
  198. static int    PdevDefaultSetAttr();
  199.  
  200. static Pdev_CallBacks pdevDefaultCallBacks = {
  201.      PdevDefaultOpen,
  202.      PdevDefaultRead,
  203.      PdevDefaultWrite,
  204.      PdevDefaultIoctl,
  205.      PdevDefaultClose,
  206.      PdevDefaultGetAttr,
  207.      PdevDefaultSetAttr,
  208. };
  209.  
  210. /*
  211.  * PDEV_MIN_BYTES        Minimum number of data bytes in request buffer.
  212.  * PFS_REQUEST_BUF_SIZE     Size of the request buffer for naming stream.
  213.  */
  214.  
  215. #define PDEV_MIN_BYTES    1024
  216. #define PDEV_REQUEST_BUF_SIZE    (sizeof(Pdev_Request) + PDEV_MIN_BYTES)
  217.  
  218. /*
  219.  * Forward references to procedures in this file:
  220.  */
  221.  
  222. static void    PdevControlRequest();
  223. static void    PdevServiceRequest();
  224. static int    PdevCleanup();
  225. static void    ReplyNoData();
  226. static void    ReplyWithData();
  227. static int    (*SetHandler())();
  228.  
  229. /*
  230.  *----------------------------------------------------------------------
  231.  *
  232.  * Pdev_Open --
  233.  *
  234.  *    Arrange to be the server for a pseudo-device.  This creates the
  235.  *    pseudo-device file, choosing a unique name if needed (see below).
  236.  *    The set of service call-backs are installed and will be called
  237.  *    when regular processes operate on the pseudo-device.  See the
  238.  *    man page for Pdev for details of the call-back interface.
  239.  *
  240.  * Results:
  241.  *    The return value is a token for the pseudo-device, which gets
  242.  *    passed to Pdev_Close.  A NULL return value
  243.  *    means that the pseudo-device could not be opened.  If realNamePtr
  244.  *    is non-NULL, *realNamePtr is filled in with a dynamically-
  245.  *    allocated string giving the actual name of the pseudo-device
  246.  *    file.
  247.  *
  248.  * Side effects:
  249.  *    A pseudo-device is opened in master mode.  If realNamePtr is
  250.  *    NULL then name is the complete name of the pseudo device;  if
  251.  *    realNamePtr is not NULL, then this procedure generates a
  252.  *    pseudo-device name of the form hostDir/nameXX, where "hostDir"
  253.  *    is the name of a standard host-specific directory for holding
  254.  *    terminal pseudo-devices and XX is an integer id appended to
  255.  *    "name" in order to find a device that isn't already in use.
  256.  *    Once this procedure returns, this module manages the pseudo
  257.  *    device to provide a simple call-back interface to service procedures.
  258.  *    I,e, for each operation on the pseudo-device by a another process,
  259.  *    a call-back for that operation is made to one of the supplied
  260.  *    service procedures.
  261.  *
  262.  *----------------------------------------------------------------------
  263.  */
  264.  
  265. Pdev_Token
  266. Pdev_Open(name, realNamePtr, requestBufSize, readBufSize, service, clientData)
  267.     char *name;            /* Name of pseudo-device file to use for
  268.                  * application interface, or key for generating
  269.                  * name (if realNamePtr != NULL).  If no
  270.                  * pseudo-device by that name exists, one
  271.                  * will be created. */
  272.     char **realNamePtr;        /* If not NULL, then use "name" as a key for
  273.                  * a name (see above) and store actual name of
  274.                  * pseudo-device here.  The memory for the
  275.                  * string is dynamically allocated. */
  276.     int requestBufSize;        /* Preferred size for the request buffer.
  277.                  * Can be <= 0 for a default size */
  278.     int readBufSize;        /* Size for optional read buffer.  Zero means
  279.                  * no buffering and we use the read call-back*/
  280.     Pdev_CallBacks *service;    /* A set of service procedures.
  281.                  * This can be NULL (or any element can be
  282.                  * NULL) in order to get a default handler
  283.                  * for all (some) operations.  The callbacks
  284.                  * can be changed with Pdev_SetupHandler */
  285.     ClientData clientData;    /* Client data associated with pseudo-device */
  286. {
  287.     int streamID;
  288.     register Pdev *pdevPtr;
  289.     int pdevOpenFlags;
  290.  
  291.     /*
  292.      * Pick a file name to use for the pseudo-device, if the caller didn't
  293.      * give us one, then open the pseudo-device as the controlling process.
  294.      */
  295.  
  296.     pdevOpenFlags = O_MASTER|O_RDWR|O_CREAT;
  297.     if (realNamePtr != NULL) {
  298.     char hostName[50];
  299.     int i;
  300.     char *actualName;
  301.  
  302.     if (gethostname(hostName, 20) != 0) {
  303.         sprintf(pdev_ErrorMsg, "couldn't get host name (%s)",
  304.             strerror(errno));
  305.         return (Pdev_Token) NULL;
  306.     } else {
  307.         /*
  308.          * Trim off domain name, if any
  309.          */
  310.         char *cp;
  311.  
  312.         cp = index(hostName, '.');
  313.         if (cp != (char *)NULL) {
  314.         *cp = '\0';
  315.         }
  316.     }
  317.     actualName = (char *) malloc((unsigned) (12 + strlen(hostName)
  318.         + strlen(name)));
  319.     for (i = 1; i < 100; i++) {
  320.         sprintf(actualName, "/hosts/%s/%s%d", hostName,
  321.             name, i);
  322.  
  323.         /*
  324.          * Because of umask, the file's mode may not actually get set
  325.          * to 0666.  Once the file is open, change the mode explicitly
  326.          * to force it.
  327.          */
  328.  
  329.         streamID = open(actualName, pdevOpenFlags, 0666);
  330.         if (streamID >= 0) {
  331.         fchmod(streamID, 0666);
  332.         *realNamePtr = actualName;
  333.         goto gotStream;
  334.         }
  335.     }
  336.     free((char *) actualName);
  337.     sprintf(pdev_ErrorMsg, 
  338.         "couldn't open a pseudo-device in \"/hosts/%s\"", hostName);
  339.     return (Pdev_Token) NULL;
  340.     } else {
  341.     streamID = open(name, pdevOpenFlags, 0666);
  342.     if (streamID < 0) {
  343.         sprintf(pdev_ErrorMsg, "couldn't open \"%s\" (%s)",
  344.             name, strerror(errno));
  345.         return (Pdev_Token) NULL;
  346.     } else {
  347.         fchmod(streamID, 0666);
  348.     }
  349.     }
  350.  
  351. gotStream:
  352.     pdevPtr = (Pdev *) malloc(sizeof(Pdev));
  353.     pdevPtr->stream.magic = PDEV_MAGIC;
  354.     pdevPtr->stream.streamID = streamID;
  355.     pdevPtr->stream.clientData = clientData;
  356.     pdevPtr->requestBufSize = requestBufSize;
  357.     pdevPtr->readBufSize = readBufSize;
  358.     List_Init(&pdevPtr->connectList);
  359.     pdevPtr->defaultService = (Pdev_CallBacks *)malloc(sizeof(Pdev_CallBacks));
  360.     if (service == (Pdev_CallBacks *)NULL) {
  361.     bzero((Address) pdevPtr->defaultService, sizeof(Pdev_CallBacks));
  362.     } else {
  363.     bcopy((Address) service, (Address) pdevPtr->defaultService,
  364.             sizeof(Pdev_CallBacks));
  365.     }
  366.     Fs_EventHandlerCreate(streamID, FS_READABLE, PdevControlRequest,
  367.         (ClientData) pdevPtr);
  368.  
  369.     return (Pdev_Token) pdevPtr;
  370. }
  371.  
  372. /*
  373.  *----------------------------------------------------------------------
  374.  *
  375.  * Pdev_Close --
  376.  *
  377.  *    Close down a pseudo-device and release all of the
  378.  *    state associated with it.
  379.  *
  380.  * Results:
  381.  *    None.
  382.  *
  383.  * Side effects:
  384.  *    Memory gets recycled, and clients on the other end of the
  385.  *    pseudo-device will probably terminate.  After this call,
  386.  *    the caller should never again use the pseudo-device.
  387.  *
  388.  *----------------------------------------------------------------------
  389.  */
  390.  
  391. void
  392. Pdev_Close(pdevToken)
  393.     Pdev_Token pdevToken;    /* Token identifying the pseudo-device.
  394.                  * This is returned from Pdev_Open. */
  395. {
  396.     register Pdev *pdevPtr = (Pdev *) pdevToken;
  397.     List_Links *listPtr;
  398.     register ServiceStream *srvPtr;
  399.  
  400.     while (!List_IsEmpty(&pdevPtr->connectList)) {
  401.     listPtr = List_First(&pdevPtr->connectList);
  402.     srvPtr = LIST_TO_SRVPTR(listPtr);
  403.     (void)PdevCleanup(srvPtr, FALSE);
  404.     }
  405.     Fs_EventHandlerDestroy(pdevPtr->stream.streamID);
  406.     close(pdevPtr->stream.streamID);
  407.     free((Address)pdevToken);
  408. }
  409.  
  410. /*
  411.  *----------------------------------------------------------------------
  412.  *
  413.  * Pdev_GetStreamID --
  414.  *
  415.  *    Return the descriptor associated with a master's pdev.  
  416.  *
  417.  * Results:
  418.  *    The streamID is returned.
  419.  *
  420.  * Side effects:
  421.  *    None.
  422.  *
  423.  *----------------------------------------------------------------------
  424.  */
  425.  
  426. int
  427. Pdev_GetStreamID(pdevToken)
  428.     Pdev_Token pdevToken;    /* Token identifying the pseudo-device.
  429.                  * This is returned from Pdev_Open. */
  430. {
  431.     register Pdev *pdevPtr = (Pdev *) pdevToken;
  432.     return(pdevPtr->stream.streamID);
  433. }
  434.  
  435.  
  436. /*
  437.  *----------------------------------------------------------------------
  438.  *
  439.  * PdevCleanup --
  440.  *
  441.  *    Called when a client has closed in order to
  442.  *    clean up any associated state.
  443.  *
  444.  * Results:
  445.  *    Returns the status from the close call-back.
  446.  *
  447.  * Side effects:
  448.  *    Calls the close-call back, then cleans up all state associated
  449.  *    with the pseudo-device.
  450.  *
  451.  *----------------------------------------------------------------------
  452.  */
  453.  
  454. static int
  455. PdevCleanup(srvPtr, sendReply)
  456.     register ServiceStream *srvPtr;    /* Service stream info. */
  457.     Boolean sendReply;            /* TRUE if we should reply to the
  458.                      * close request.  This is done in
  459.                      * normal termination.  FALSE means
  460.                      * no reply needed, used to close
  461.                      * pending connections when the
  462.                      * server is bailing out */
  463. {
  464.     int status;
  465.  
  466.     status = (*srvPtr->service->close)(&srvPtr->stream);
  467. #ifdef lint
  468.     status = PdevDefaultClose(&srvPtr->stream);
  469. #endif /* lint */
  470.  
  471.     if (sendReply) {
  472.     ReplyNoData(srvPtr, status, 0);
  473.     }
  474.     List_Remove(&srvPtr->links);
  475.     Fs_EventHandlerDestroy(srvPtr->stream.streamID);
  476.     close(srvPtr->stream.streamID);
  477.     free((char *) srvPtr->requestBuf);
  478.     if (srvPtr->service != (Pdev_CallBacks *)NULL) {
  479.     free((char *) srvPtr->service);
  480.     }
  481.     if (srvPtr->readBuf != NULL) {
  482.     free(srvPtr->readBuf);
  483.     }
  484.     if (srvPtr->ioctlOutBuf != NULL) {
  485.     free(srvPtr->ioctlOutBuf);
  486.     }
  487.     free((char *) srvPtr);
  488.     return status;
  489. }
  490.  
  491. /*
  492.  *----------------------------------------------------------------------
  493.  *
  494.  * PdevControlRequest --
  495.  *
  496.  *    This procedure is invoked by Fs_Dispatcher when the control
  497.  *    stream for a pseudo-device is readable.  This means that
  498.  *    a new stream is being opened on the pdev.
  499.  *
  500.  * Results:
  501.  *    None.
  502.  *
  503.  * Side effects:
  504.  *    Add a new service stream to the pdev.
  505.  *
  506.  *----------------------------------------------------------------------
  507.  */
  508.  
  509. static void
  510. PdevControlRequest(pdevPtr)
  511.     register Pdev *pdevPtr;    /* Pdev whose control stream is ready. */
  512. {
  513.     Pdev_Notify notify;
  514.     int numBytes;
  515.  
  516.     /*
  517.      * Read the control stream for a message containing a new streamID.
  518.      */
  519.  
  520.     numBytes = read(pdevPtr->stream.streamID, (char *) ¬ify, sizeof(notify));
  521.     if (numBytes != sizeof(notify)) {
  522.     panic("%s; status \"%s\", count %d\n",
  523.         "PdevControlRequest couldn't read control stream",
  524.         strerror(errno), numBytes);
  525.     }
  526.     if (notify.magic != PDEV_NOTIFY_MAGIC) {
  527.     panic("%s: %d\n", "PdevControlRequest got bad notify magic number",
  528.         notify.magic);
  529.     }
  530.     (void) PdevSetup(notify.newStreamID, (Address)pdevPtr,
  531.         &pdevPtr->connectList, pdevPtr->requestBufSize,
  532.         pdevPtr->readBufSize, (char *)0, pdevPtr->defaultService, 0);
  533. }
  534.  
  535. /*
  536.  *----------------------------------------------------------------------
  537.  *
  538.  * PdevSetup --
  539.  *
  540.  *    Set up state for a pseudo-device connection. This includes a request
  541.  *    buffer used by the kernel to pass client requests to us and a set
  542.  *    of service call-back procedures.
  543.  *    
  544.  * Results:
  545.  *    A pointer to the user's handle on the service stream.
  546.  *
  547.  * Side effects:
  548.  *    Allocates and initializes state.  Makes IOControls to set
  549.  *    attributes of the pdev connection.
  550.  *
  551.  *----------------------------------------------------------------------
  552.  */
  553.  
  554. Pdev_Stream *
  555. PdevSetup(streamID, backPointer, streamList, reqBufSize, readBufSize, readBuf, service, selectBits)
  556.     int streamID;        /* Service stream */
  557.     Address backPointer;    /* Pointer to global state */
  558.     List_Links *streamList;    /* List of pseudo-device streams */
  559.     int reqBufSize;        /* Size for the request buffer */
  560.     int readBufSize;        /* Size for the read buffer, if any */
  561.     char *readBuf;        /* The read buffer itself, NULL if it should
  562.                  * be allocated here */
  563.     Pdev_CallBacks *service;    /* Set of service call-backs */
  564.     int selectBits;        /* Initial select state of the connection */
  565. {
  566.     register ServiceStream *srvPtr;
  567.     Pdev_SetBufArgs setBuf;
  568.     int false = 0;
  569.  
  570.     srvPtr = (ServiceStream *) malloc(sizeof(ServiceStream));
  571.     List_InitElement(&srvPtr->links);
  572.     List_Insert(&srvPtr->links, LIST_ATFRONT(streamList));
  573.     srvPtr->stream.magic = PDEV_STREAM_MAGIC;
  574.     srvPtr->stream.streamID = streamID;
  575.     srvPtr->stream.clientData = 0;
  576.     srvPtr->parent = backPointer;
  577.     srvPtr->service = (Pdev_CallBacks *)malloc(sizeof(Pdev_CallBacks));
  578.     bcopy((Address) service, (Address) srvPtr->service,
  579.         sizeof(Pdev_CallBacks));
  580.     if (srvPtr->service->open == (int (*)())NULL) {
  581.     srvPtr->service->open = pdevDefaultCallBacks.open;
  582.     }
  583.     if (srvPtr->service->read == (int (*)())NULL) {
  584.     srvPtr->service->read = pdevDefaultCallBacks.read;
  585.     }
  586.     if (srvPtr->service->write == (int (*)())NULL) {
  587.     srvPtr->service->write = pdevDefaultCallBacks.write;
  588.     }
  589.     if (srvPtr->service->ioctl == (int (*)())NULL) {
  590.     srvPtr->service->ioctl = pdevDefaultCallBacks.ioctl;
  591.     }
  592.     if (srvPtr->service->close == (int (*)())NULL) {
  593.     srvPtr->service->close = pdevDefaultCallBacks.close;
  594.     }
  595.     if (srvPtr->service->getAttr == (int (*)())NULL) {
  596.     srvPtr->service->getAttr = pdevDefaultCallBacks.getAttr;
  597.     }
  598.     if (srvPtr->service->setAttr == (int (*)())NULL) {
  599.     srvPtr->service->setAttr = pdevDefaultCallBacks.setAttr;
  600.     }
  601.     if (readBufSize > 0) {
  602.     /*
  603.      * Server wants a read buffer.  We allocate it now and declare
  604.      * it to the kernel with the IOC_PDEV_SET_BUFS call below.
  605.      */
  606.     if (readBuf == NULL) {
  607.         srvPtr->readBuf = malloc(readBufSize);
  608.     } else {
  609.         srvPtr->readBuf = readBuf;
  610.     }
  611.     srvPtr->readBufSize = readBufSize;
  612.     } else {
  613.     /*
  614.      * No read buffering, but we will allocate a buffer for passing
  615.      * to the read service call-back later.
  616.      */
  617.     srvPtr->readBuf = NULL;
  618.     srvPtr->readBufSize = 0;
  619.     }
  620.     srvPtr->ioctlOutBuf = NULL;
  621.     srvPtr->ioctlBufSize = 0;
  622.  
  623.     reqBufSize = max(PDEV_REQUEST_BUF_SIZE, reqBufSize);
  624.     srvPtr->requestBuf = (Address) malloc(reqBufSize);
  625.     setBuf.requestBufAddr = srvPtr->requestBuf;
  626.     setBuf.requestBufSize = reqBufSize;
  627.     setBuf.readBufAddr = srvPtr->readBuf;
  628.     setBuf.readBufSize = srvPtr->readBufSize;
  629.     Fs_IOControl(streamID, IOC_PDEV_WRITE_BEHIND,
  630.             sizeof(int), (Address)&false, 0, (Address) NULL);
  631.     Fs_IOControl(streamID, IOC_PDEV_SET_BUF,
  632.             sizeof(Pdev_SetBufArgs), (Address)&setBuf,
  633.             0, (Address) NULL);
  634.     Fs_IOControl(streamID, IOC_PDEV_READY,
  635.             sizeof(int), (Address)&selectBits, 0, (Address) NULL);
  636.  
  637.     Fs_EventHandlerCreate(streamID, FS_READABLE, PdevServiceRequest,
  638.         (ClientData) srvPtr);
  639.  
  640.     return ((Pdev_Stream *)srvPtr);
  641. }
  642.  
  643. /*
  644.  *----------------------------------------------------------------------
  645.  *
  646.  * PdevServiceRequest --
  647.  *
  648.  *    This procedure is invoked by Fs_Dispatch when a request appears
  649.  *    for an service stream.   This procedure reads the request and
  650.  *    dispatches to a routine to handle the request.
  651.  *
  652.  * Results:
  653.  *    None.
  654.  *
  655.  * Side effects:
  656.  *    Makes the call-backs to the service procedures passed to Pdev_Open.
  657.  *    Generates pseudo-device replies to complete the protocol with
  658.  *    the kernel.
  659.  *
  660.  *----------------------------------------------------------------------
  661.  */
  662.  
  663. static void
  664. PdevServiceRequest(srvPtr)
  665.     register ServiceStream *srvPtr;    /* Application stream that has a
  666.                      * request ready for processing. */
  667. {
  668.     Pdev_BufPtrs bufPtrs;
  669.     Pdev_Signal signalInfo;
  670.     Pdev_Request *requestPtr;
  671.     Address dataPtr;        /* pointer to data following header */
  672.     Pdev_Reply reply;
  673.     int numBytes;
  674.     int status;
  675.     int selectBits;
  676.     int savedFirstByte;
  677.  
  678.     /*
  679.      * Read the current pointers for the request buffer.
  680.      */
  681.  
  682.     numBytes = read(srvPtr->stream.streamID, (char *) &bufPtrs,
  683.         sizeof(Pdev_BufPtrs));
  684.     if (numBytes != sizeof(Pdev_BufPtrs)) {
  685.     panic("%s; status \"%s\", count %d\n",
  686.         "PdevServiceRequest had trouble reading request buffer pointers",
  687.         strerror(errno), numBytes);
  688.     }
  689.     if (bufPtrs.magic != PDEV_BUF_PTR_MAGIC) {
  690.     panic("%s: %d\n", "PdevServiceRequest got bad pointer magic number",
  691.         bufPtrs.magic);
  692.     }
  693.     savedFirstByte = bufPtrs.requestFirstByte;
  694.     /*
  695.      * While there are still requests in the buffer, service them.
  696.      */
  697.     while (bufPtrs.requestFirstByte < bufPtrs.requestLastByte) {
  698.     requestPtr =
  699.         (Pdev_Request *)&srvPtr->requestBuf[bufPtrs.requestFirstByte];
  700.     if (requestPtr->hdr.magic != PDEV_REQUEST_MAGIC) {
  701.         printf("PdevServiceRequest, alignment error: firstByte %d currentByte %d lastByte %d magic %x\n",
  702.           savedFirstByte,
  703.           bufPtrs.requestFirstByte, bufPtrs.requestLastByte,
  704.           requestPtr->hdr.magic);
  705.         /*
  706.          * Ignore bogus request.
  707.          */
  708.         bufPtrs.requestFirstByte = bufPtrs.requestLastByte + 1;
  709.         break;
  710.     }
  711.     dataPtr = (Address)((int)requestPtr + sizeof(Pdev_Request));
  712.     signalInfo.signal = 0;
  713.     signalInfo.code = 0;
  714.  
  715.     switch (requestPtr->hdr.operation) {
  716.         case PDEV_OPEN: {
  717.         /*
  718.          * This is the first operation on a pseudo-device.  The
  719.          * server can set srvPtr->private here, which will be
  720.          * passed into the other handlers.
  721.          */
  722.         Pdev *pdevPtr;
  723.         if (pdev_Trace) {
  724.             fprintf(stderr, "OPEN %d: uid %d use %x",
  725.                 srvPtr->stream.streamID,
  726.                 requestPtr->param.open.uid,
  727.                 requestPtr->param.open.flags);
  728.         }
  729.         pdevPtr = (Pdev *)srvPtr->parent;
  730.         status = (*srvPtr->service->open)
  731.                 (pdevPtr->stream.clientData, &srvPtr->stream,
  732.                 srvPtr->readBuf,
  733.                 requestPtr->param.open.flags,
  734.                 requestPtr->param.open.pid,
  735.                 requestPtr->param.open.hostID,
  736.                 requestPtr->param.open.uid,
  737.                 &selectBits);
  738. #ifdef lint
  739.         status = PdevDefaultOpen(pdevPtr->stream.clientData, &srvPtr->stream,
  740.                 srvPtr->readBuf,
  741.                 requestPtr->param.open.flags,
  742.                 requestPtr->param.open.pid,
  743.                 requestPtr->param.open.hostID,
  744.                 requestPtr->param.open.uid,
  745.                 &selectBits);
  746. #endif /* lint */
  747.         ReplyNoData(srvPtr, status, selectBits);
  748.         break;
  749.         }
  750.         case PDEV_CLOSE:
  751.         if (pdev_Trace) {
  752.             fprintf(stderr, "CLOSE %d", srvPtr->stream.streamID);
  753.         }
  754.         status = PdevCleanup(srvPtr, TRUE);
  755.         break;
  756.         case PDEV_READ: {
  757.         /*
  758.          * For reading we pass in a pre-allocated buffer, but also
  759.          * allow the read procedure to use a different buffer.  If it
  760.          * does change the buffer it also indicates if we should
  761.          * free the new buffer after we reply.  We hold onto our
  762.          * own srvPtr->readBuf until the connection is closed.
  763.          */
  764.         Boolean freeIt = FALSE;
  765.  
  766.         if (pdev_Trace) {
  767.             fprintf(stderr, "READ %d bytes at offset %d\n",
  768.             requestPtr->hdr.replySize,
  769.             requestPtr->param.read.offset);
  770.         }
  771.  
  772.         reply.replySize = requestPtr->hdr.replySize;
  773.         if (reply.replySize > srvPtr->readBufSize) {
  774.             /*
  775.              * Increase the read buffer size.
  776.              */
  777.             if (srvPtr->readBuf != NULL) {
  778.             free(srvPtr->readBuf);
  779.             }
  780.             srvPtr->readBuf = malloc(reply.replySize);
  781.             srvPtr->readBufSize = reply.replySize;
  782.         }
  783.         requestPtr->param.read.buffer = srvPtr->readBuf;
  784.         status = (*srvPtr->service->read)(&srvPtr->stream,
  785.                 &requestPtr->param.read, &freeIt,
  786.                 &reply.selectBits,
  787.                 &signalInfo);
  788. #ifdef lint
  789.         status = PdevDefaultRead(&srvPtr->stream,
  790.                 &requestPtr->param.read, &freeIt,
  791.                 &reply.selectBits,
  792.                 &signalInfo);
  793. #endif /* lint */
  794.  
  795.         reply.replySize = requestPtr->param.read.length;
  796.         reply.replyBuf = requestPtr->param.read.buffer;
  797.         ReplyWithData(srvPtr, status, &reply, &signalInfo);
  798.         if (freeIt &&
  799.             (requestPtr->param.read.buffer != srvPtr->readBuf)) {
  800.             free(requestPtr->param.read.buffer);
  801.         }
  802.         break;
  803.         }
  804.         case PDEV_WRITE_ASYNC:
  805.         case PDEV_WRITE: {
  806.         if (pdev_Trace) {
  807.             fprintf(stderr, "WRITE %d bytes at offset %d",
  808.             requestPtr->hdr.requestSize,
  809.             requestPtr->param.read.offset);
  810.         }
  811.         requestPtr->param.write.buffer = dataPtr;
  812.         status = (*srvPtr->service->write)(&srvPtr->stream,
  813.                 (requestPtr->hdr.operation == PDEV_WRITE_ASYNC),
  814.                 &requestPtr->param.write,
  815.                 &reply.selectBits,
  816.                 &signalInfo);
  817. #ifdef lint
  818.         status = PdevDefaultWrite(&srvPtr->stream,
  819.                 (requestPtr->hdr.operation == PDEV_WRITE_ASYNC),
  820.                 &requestPtr->param.write,
  821.                 &reply.selectBits,
  822.                 &signalInfo);
  823. #endif /* lint */
  824.         if (requestPtr->hdr.operation == PDEV_WRITE) {
  825.             reply.replySize = sizeof(int);
  826.             reply.replyBuf = (Address)&requestPtr->param.write.length;
  827.             ReplyWithData(srvPtr, status, &reply, &signalInfo);
  828.         }
  829.         break;
  830.         }
  831.         case PDEV_IOCTL: {
  832.         if (pdev_Trace) {
  833.             fprintf(stderr, "IOCTL %d", requestPtr->param.ioctl.command);
  834.         }
  835.         /*
  836.          * The kernel sets up the sizes of the two buffers,
  837.          * but we have our own notion of where they are.
  838.          * We grow the out buffer if needed, for example,
  839.          * and the inBuffer is sitting in the request buffer at dataPtr.
  840.          */
  841.         reply.replySize = requestPtr->hdr.replySize;
  842.         if (reply.replySize > srvPtr->ioctlBufSize) {
  843.             if (srvPtr->ioctlOutBuf != NULL) {
  844.             free(srvPtr->ioctlOutBuf);
  845.             }
  846.             srvPtr->ioctlOutBuf = malloc(reply.replySize);
  847.             srvPtr->ioctlBufSize = reply.replySize;
  848.         }
  849.         requestPtr->param.ioctl.inBuffer = dataPtr;
  850.         requestPtr->param.ioctl.outBuffer = srvPtr->ioctlOutBuf;
  851.         status = (*srvPtr->service->ioctl)(&srvPtr->stream,
  852.                  &requestPtr->param.ioctl,
  853.                  &reply.selectBits,
  854.                  &signalInfo);
  855. #ifdef lint
  856.         status = PdevDefaultIoctl(&srvPtr->stream,
  857.                  &requestPtr->param.ioctl,
  858.                  &reply.selectBits,
  859.                  &signalInfo);
  860. #endif /* lint */
  861.         reply.replyBuf = srvPtr->ioctlOutBuf;
  862.         reply.replySize = requestPtr->param.ioctl.outBufSize;
  863.         ReplyWithData(srvPtr, status, &reply, &signalInfo);
  864.         break;
  865.         }
  866.         case PDEV_GET_ATTR: {
  867.         Fs_Attributes attr;
  868.  
  869.         if (pdev_Trace) {
  870.             fprintf(stderr, "GET ATTR");
  871.         }
  872.         status = (*srvPtr->service->getAttr)(&srvPtr->stream,
  873.                 &attr, &reply.selectBits);
  874. #ifdef lint
  875.         status = PdevDefaultGetAttr(&srvPtr->stream,
  876.                 &attr, &reply.selectBits);
  877. #endif /* lint */
  878.         if (status == SUCCESS) {
  879.             reply.replyBuf = (Address)&attr;
  880.             reply.replySize = sizeof(Fs_Attributes);
  881.             ReplyWithData(srvPtr, status, &reply, (Pdev_Signal *)NIL);
  882.         } else {
  883.             ReplyNoData(srvPtr, status, reply.selectBits);
  884.         }
  885.         break;
  886.         }
  887.         case PDEV_SET_ATTR: {
  888.         if (pdev_Trace) {
  889.             fprintf(stderr, "SET ATTR %x", requestPtr->param.setAttr.flags);
  890.         }
  891.         status = (*srvPtr->service->setAttr)(&srvPtr->stream,
  892.                 requestPtr->param.setAttr.flags,
  893.                 requestPtr->param.setAttr.uid,
  894.                 requestPtr->param.setAttr.gid,
  895.                 (Fs_Attributes *)dataPtr, &reply.selectBits);
  896. #ifdef lint
  897.         status = PdevDefaultSetAttr(&srvPtr->stream,
  898.                 requestPtr->param.setAttr.flags,
  899.                 requestPtr->param.setAttr.uid,
  900.                 requestPtr->param.setAttr.gid,
  901.                 (Fs_Attributes *)dataPtr, &reply.selectBits);
  902. #endif /* lint */
  903.         ReplyNoData(srvPtr, status, reply.selectBits);
  904.         break;
  905.         }
  906.         default:
  907.         panic("PdevServiceRequest: bad request on request stream: %d\n",
  908.             requestPtr->hdr.operation);
  909.     }
  910.     if (pdev_Trace) {
  911.         fprintf(stderr, " Returns %x\n", status);
  912.     }
  913.     /*
  914.      * Move to the next request message.
  915.      */
  916.     bufPtrs.requestFirstByte += requestPtr->hdr.messageSize;
  917.     }
  918.     /*
  919.      * Tell the kernel we processed the requests.
  920.      */
  921.     Fs_IOControl(srvPtr->stream.streamID, IOC_PDEV_SET_PTRS,
  922.             sizeof(Pdev_BufPtrs), (Address)&bufPtrs,
  923.             0, (Address) NULL);
  924. }
  925.  
  926. /*
  927.  *----------------------------------------------------------------------
  928.  *
  929.  * ReplyNoData --
  930.  *
  931.  *    Send a reply back with no data;  just a return status.  This
  932.  *    procedure is most often used for error returns.
  933.  *
  934.  * Results:
  935.  *    None.
  936.  *
  937.  * Side effects:
  938.  *    The application will receive status as the return from the
  939.  *    system call it invoked.
  940.  *
  941.  *----------------------------------------------------------------------
  942.  */
  943.  
  944. static void
  945. ReplyNoData(srvPtr, status, selectBits)
  946.     ServiceStream *srvPtr;    /* Application stream info. */
  947.     int status;    /* Error code to send to application. */
  948.     int selectBits;        /* Current select state for the stream */
  949. {
  950.     Pdev_Reply reply;
  951.  
  952.     reply.magic = PDEV_REPLY_MAGIC;
  953.     reply.selectBits = selectBits;
  954.     if (status == EWOULDBLOCK) {
  955.     status = FS_WOULD_BLOCK;
  956.     } else {
  957.     status = Compat_MapToSprite(status);
  958.     }
  959.     reply.status = status;
  960.     reply.replySize = 0;
  961.     reply.replyBuf = NULL;
  962.     reply.signal = 0;
  963.     reply.code = 0;
  964.     status = Fs_IOControl(srvPtr->stream.streamID, IOC_PDEV_REPLY,
  965.         sizeof(Pdev_Reply), (Address) &reply, 0, (Address) NULL);
  966.     if (status != SUCCESS) {
  967.     panic("%s; status \"%s\"\n", "Reply couldn't send pdev reply",
  968.         Stat_GetMsg(status));
  969.     }
  970. }
  971.  
  972. /*
  973.  *----------------------------------------------------------------------
  974.  *
  975.  * ReplyWithData --
  976.  *
  977.  *    Send a reply back along with some data.
  978.  *
  979.  * Results:
  980.  *    None.
  981.  *
  982.  * Side effects:
  983.  *    The application will receive status as the return from the
  984.  *    system call it invoked.
  985.  *
  986.  *----------------------------------------------------------------------
  987.  */
  988.  
  989. static void
  990. ReplyWithData(srvPtr, status, replyPtr, sigPtr)
  991.     ServiceStream *srvPtr;    /* Application stream info. */
  992.     int status;            /* Error code to send to application. */
  993.     Pdev_Reply *replyPtr;    /* Partially completed reply.  The replySize,
  994.                  * data area, and selectBits should be set. */
  995.     Pdev_Signal *sigPtr;    /* Signal to return, if any */
  996. {
  997.     if (status == EWOULDBLOCK) {
  998.     status = FS_WOULD_BLOCK;
  999.     } else {
  1000.     status = Compat_MapToSprite(status);
  1001.     }
  1002.     if (sigPtr != (Pdev_Signal *)NIL) {
  1003.     replyPtr->signal = sigPtr->signal;
  1004.     replyPtr->code = sigPtr->code;
  1005.     } else {
  1006.     replyPtr->signal = 0;
  1007.     replyPtr->code = 0;
  1008.     }
  1009.     if (replyPtr->replySize <= PDEV_SMALL_DATA_LIMIT) {
  1010.     Pdev_ReplyData replyData;
  1011.  
  1012.     replyData.magic = PDEV_REPLY_DATA_MAGIC;
  1013.     replyData.status = status;
  1014.     replyData.selectBits = replyPtr->selectBits;
  1015.     replyData.replySize = replyPtr->replySize;
  1016.     replyData.signal = replyPtr->signal;
  1017.     replyData.code = replyPtr->code;
  1018.     bcopy(replyPtr->replyBuf, replyData.data, replyPtr->replySize);
  1019.     status = Fs_IOControl(srvPtr->stream.streamID, IOC_PDEV_SMALL_REPLY,
  1020.         sizeof(Pdev_ReplyData), (Address)&replyData, 0, (Address) NULL);
  1021.     } else {
  1022.     replyPtr->magic = PDEV_REPLY_MAGIC;
  1023.     replyPtr->status = status;
  1024.     status = Fs_IOControl(srvPtr->stream.streamID, IOC_PDEV_REPLY,
  1025.             sizeof(Pdev_Reply), (Address) replyPtr, 0, (Address) NULL);
  1026.     }
  1027.     if (status != SUCCESS) {
  1028.     panic("%s; status \"%s\"\n", "ReplyWithData couldn't send pdev reply",
  1029.         Stat_GetMsg(status));
  1030.     }
  1031. }
  1032.  
  1033. /*
  1034.  *----------------------------------------------------------------------
  1035.  *
  1036.  * Pdev_EnumStreams --
  1037.  *
  1038.  *    Apply a function to all service streams associated with a pdev.
  1039.  *
  1040.  * Results:
  1041.  *    0 means all the applications of the function returned 0 as well.
  1042.  *    If the function returns non-zero when applied to a stream then
  1043.  *    the enumeration is stopped and that value is returned.
  1044.  *
  1045.  * Side effects:
  1046.  *    None here.
  1047.  *
  1048.  *----------------------------------------------------------------------
  1049.  */
  1050.  
  1051. int
  1052. Pdev_EnumStreams(pdevToken, func, clientData)
  1053.     Pdev_Token pdevToken;
  1054.     int (*func)();
  1055.     ClientData clientData;
  1056. {
  1057.     register Pdev *pdevPtr = (Pdev *)pdevToken;
  1058.     register List_Links *listPtr;
  1059.     register ServiceStream *srvPtr;
  1060.     register int status;
  1061.  
  1062.     if (pdevPtr->stream.magic != (unsigned int)PDEV_MAGIC) {
  1063.     fprintf(stderr, "Pdev_EnumStreams passed bad pdevToken\n");
  1064.     return -1;
  1065.     }
  1066.     LIST_FORALL(&pdevPtr->connectList, listPtr) {
  1067.     srvPtr = LIST_TO_SRVPTR(listPtr);
  1068.     status = (*func)((Pdev_Stream *)srvPtr, clientData);
  1069.     if (status != 0) {
  1070.         return(status);
  1071.     }
  1072.     }
  1073.     return(0);
  1074. }
  1075.  
  1076.  
  1077. /*
  1078.  *----------------------------------------------------------------------
  1079.  *
  1080.  * Pfs_SetDefaultHandler --
  1081.  *
  1082.  *    Set a default handler for a particular PDEV request.  If the handler is
  1083.  *    NULL then a default procedure replaces the existing handler.
  1084.  *    The default handlers are used when new connections are established
  1085.  *    to the pseudo-device.
  1086.  * 
  1087.  * Results:
  1088.  *    The old handler.
  1089.  *
  1090.  * Side effects:
  1091.  *    Updates the call-back list.
  1092.  *
  1093.  *----------------------------------------------------------------------
  1094.  */
  1095. int (*
  1096. Pdev_SetDefaultHandler(token, operation, handler))()
  1097.     Pdev_Token token;        /* Returned from Pdev_Open */
  1098.     int operation;        /* Which operation to set the handler for */
  1099.     int (*handler)();        /* The callback procedure */
  1100. {
  1101.     register Pdev        *pdevPtr = (Pdev *)token;
  1102.     register int        (*oldHandler)();
  1103.  
  1104.     if (pdevPtr->stream.magic != (unsigned int)PDEV_MAGIC) {
  1105.     fprintf(stderr, "Bad token passed to Pdev_SetHandler\n");
  1106.     return (int (*)())NULL;
  1107.     }
  1108.  
  1109.     oldHandler = SetHandler(pdevPtr->defaultService, operation, handler);
  1110.     return oldHandler;
  1111. }
  1112.  
  1113. /*
  1114.  *----------------------------------------------------------------------
  1115.  *
  1116.  * Pfs_SetStreamHandler --
  1117.  *
  1118.  *    Set a handler for a particular stream and PDEV request.  If the handler
  1119.  *    is NULL then a default procedure replaces the existing handler.
  1120.  *    This call only affects the handler for the given stream to the
  1121.  *    pseudo-device.
  1122.  * 
  1123.  * Results:
  1124.  *    The old handler.
  1125.  *
  1126.  * Side effects:
  1127.  *    Updates the call-back list.
  1128.  *
  1129.  *----------------------------------------------------------------------
  1130.  */
  1131. int (*
  1132. Pdev_SetStreamHandler(streamPtr, operation, handler))()
  1133.     Pdev_Stream *streamPtr;/* Handler for stream to pseudo-device */
  1134.     int operation;        /* Which operation to set the handler for */
  1135.     int (*handler)();        /* The callback procedure */
  1136. {
  1137.     register ServiceStream    *srvPtr = (ServiceStream *)streamPtr;
  1138.     register int        (*oldHandler)();
  1139.  
  1140.     if (srvPtr->stream.magic != (unsigned int)PDEV_STREAM_MAGIC) {
  1141.     fprintf(stderr, "Bad token passed to Pdev_SetHandler\n");
  1142.     return (int (*)())NULL;
  1143.     }
  1144.  
  1145.     oldHandler = SetHandler(srvPtr->service, operation, handler);
  1146.     return oldHandler;
  1147. }
  1148.  
  1149. /*
  1150.  *----------------------------------------------------------------------
  1151.  *
  1152.  * SetHandler --
  1153.  *
  1154.  *    Set the handler for a pseudo-device operation and return the
  1155.  *    old handler.
  1156.  *
  1157.  * Results:
  1158.  *    The old handler.
  1159.  *
  1160.  * Side effects:
  1161.  *    Change the handler.
  1162.  *
  1163.  *----------------------------------------------------------------------
  1164.  */
  1165.  
  1166. static int (*
  1167. SetHandler(service, operation, handler))()
  1168.     Pdev_CallBacks *service;
  1169.     int operation;
  1170.     int (*handler)();
  1171. {
  1172.     int (*oldHandler)();
  1173.  
  1174.     switch (operation) {
  1175.     case PDEV_OPEN:
  1176.         oldHandler = service->open;
  1177.         if (handler == (int (*)())NULL) {
  1178.         service->open = pdevDefaultCallBacks.open;
  1179.         } else {
  1180.         service->open = handler;
  1181.         }
  1182.         break;
  1183.     case PDEV_CLOSE:
  1184.         oldHandler = service->close;
  1185.         if (handler == (int (*)())NULL) {
  1186.         service->close = pdevDefaultCallBacks.close;
  1187.         } else {
  1188.         service->close = handler;
  1189.         }
  1190.         break;
  1191.     case PDEV_READ:
  1192.         oldHandler = service->read;
  1193.         if (handler == (int (*)())NULL) {
  1194.         service->read = pdevDefaultCallBacks.read;
  1195.         } else {
  1196.         service->read = handler;
  1197.         }
  1198.         break;
  1199.     case PDEV_WRITE:
  1200.         oldHandler = service->write;
  1201.         if (handler == (int (*)())NULL) {
  1202.         service->write = pdevDefaultCallBacks.write;
  1203.         } else {
  1204.         service->write = handler;
  1205.         }
  1206.         break;
  1207.     case PDEV_IOCTL:
  1208.         oldHandler = service->ioctl;
  1209.         if (handler == (int (*)())NULL) {
  1210.         service->ioctl = pdevDefaultCallBacks.ioctl;
  1211.         } else {
  1212.         service->ioctl = handler;
  1213.         }
  1214.         break;
  1215.     case PDEV_GET_ATTR:
  1216.         oldHandler = service->getAttr;
  1217.         if (handler == (int (*)())NULL) {
  1218.         service->getAttr = pdevDefaultCallBacks.getAttr;
  1219.         } else {
  1220.         service->getAttr = handler;
  1221.         }
  1222.         break;
  1223.     case PDEV_SET_ATTR:
  1224.         oldHandler = service->setAttr;
  1225.         if (handler == (int (*)())NULL) {
  1226.         service->setAttr = pdevDefaultCallBacks.setAttr;
  1227.         } else {
  1228.         service->setAttr = handler;
  1229.         }
  1230.         break;
  1231.     default:
  1232.         fprintf(stderr, "Bad operation passed to Pdev_SetHandler");
  1233.         oldHandler = (int (*)())NULL;
  1234.         break;
  1235.     }
  1236.     return oldHandler;
  1237. }
  1238.  
  1239. /*
  1240.  *----------------------------------------------------------------------
  1241.  *
  1242.  * PdevDefaultOpen --
  1243.  *
  1244.  *    Default procedure is called when an PDEV_OPEN request is
  1245.  *    received over an service stream.
  1246.  *
  1247.  * Results:
  1248.  *    Returns SUCCESS and the select state of the pseudo-device.
  1249.  *
  1250.  * Side effects:
  1251.  *    None.
  1252.  *
  1253.  *----------------------------------------------------------------------
  1254.  */
  1255. /*ARGSUSED*/
  1256. static int
  1257. PdevDefaultOpen(clientData, streamPtr, readBuf, flags, procID, hostID,
  1258.     uid, selectBitsPtr)
  1259.     ClientData clientData;    /* Client data associated with pseudo-device */
  1260.     Pdev_Stream *streamPtr;    /* Identifies open stream */
  1261.     char *readBuf;        /* Optional read buffer */
  1262.     int flags;            /* Flags passed to open system call */
  1263.     int procID;            /* Process ID doing the open */
  1264.     int hostID;            /* Host on which process is executing */
  1265.     int uid;            /* User id of process */
  1266.     int *selectBitsPtr;        /* Return - select state of pseudo-device */
  1267. {
  1268.     *selectBitsPtr = FS_READABLE | FS_WRITABLE;
  1269.     return(SUCCESS);
  1270. }
  1271.  
  1272. /*
  1273.  *----------------------------------------------------------------------
  1274.  *
  1275.  * PdevDefaultClose --
  1276.  *
  1277.  *    Default procedure is called when an PDEV_CLOSE request is
  1278.  *    received over an service stream.
  1279.  *
  1280.  * Results:
  1281.  *    Returns SUCCESS and the select state of the pseudo-device.
  1282.  *
  1283.  * Side effects:
  1284.  *    None.
  1285.  *
  1286.  *----------------------------------------------------------------------
  1287.  */
  1288. /*ARGSUSED*/
  1289. static int
  1290. PdevDefaultClose(streamPtr)
  1291.     Pdev_Stream *streamPtr;
  1292. {
  1293.     return(SUCCESS);
  1294. }
  1295.  
  1296. /*
  1297.  *----------------------------------------------------------------------
  1298.  *
  1299.  * PdevDefaultRead --
  1300.  *
  1301.  *    The default read procedure.  This simulates EOF by returning
  1302.  *    SUCCESS but no characters.
  1303.  *
  1304.  * Results:
  1305.  *    None.
  1306.  *
  1307.  * Side effects:
  1308.  *    None.
  1309.  *
  1310.  *----------------------------------------------------------------------
  1311.  */
  1312. /*ARGSUSED*/
  1313. static int
  1314. PdevDefaultRead(streamPtr, readPtr, freeItPtr, selectBitsPtr, sigPtr)
  1315.     Pdev_Stream *streamPtr;    /* Service stream. */
  1316.     Pdev_RWParam *readPtr;    /* Read parameter block. */
  1317.     Boolean *freeItPtr;        /* Return indicates if *bufferPtr is malloc'd */
  1318.     int *selectBitsPtr;        /* Return - the select state of the pdev */
  1319.     Pdev_Signal *sigPtr;    /* Return - signal to generate. */
  1320. {
  1321.     *freeItPtr = FALSE;
  1322.     readPtr->length = 0;
  1323.     *selectBitsPtr = FS_READABLE | FS_WRITABLE;
  1324.     return(SUCCESS);
  1325. }
  1326.  
  1327. /*
  1328.  *----------------------------------------------------------------------
  1329.  *
  1330.  * PdevDefaultWrite --
  1331.  *
  1332.  *    The default write procedure.  This accepts and discards all data.
  1333.  *
  1334.  * Results:
  1335.  *    None.
  1336.  *
  1337.  * Side effects:
  1338.  *    None.
  1339.  *
  1340.  *----------------------------------------------------------------------
  1341.  */
  1342.  
  1343. /*ARGSUSED*/
  1344. static int
  1345. PdevDefaultWrite(streamPtr, async, writePtr, selectBitsPtr, sigPtr)
  1346.     Pdev_Stream *streamPtr;    /* Private data */
  1347.     int async;            /* TRUE if asynchronous and no reply needed */
  1348.     Pdev_RWParam *writePtr;    /* Write parameter block. */
  1349.     int *selectBitsPtr;        /* Result - select state of the pseudo-device */
  1350.     Pdev_Signal *sigPtr;    /* Return - signal to generate. */
  1351. {
  1352.     *selectBitsPtr = FS_READABLE | FS_WRITABLE;
  1353.     return(SUCCESS);
  1354. }
  1355.  
  1356. /*
  1357.  *----------------------------------------------------------------------
  1358.  *
  1359.  * PdevDefaultIoctl --
  1360.  *
  1361.  *    The default IOControl handling procedure called when an
  1362.  *    PDEV_IOCONTROL request is received over a request stream.
  1363.  *
  1364.  * Results:
  1365.  *    None.
  1366.  *
  1367.  * Side effects
  1368.  *    None.
  1369.  *
  1370.  *----------------------------------------------------------------------
  1371.  */
  1372. /*ARGSUSED*/
  1373. static int
  1374. PdevDefaultIoctl(streamPtr, ioctlPtr, selectBitsPtr, sigPtr)
  1375.     Pdev_Stream *streamPtr;    /* Stream to service. */
  1376.     Pdev_IOCParam *ioctlPtr;    /* ioctl parameter block. */
  1377.     int *selectBitsPtr;        /* Return - select state of pdev. */
  1378.     Pdev_Signal *sigPtr;    /* Return - signal to generate. */
  1379. {
  1380.     ioctlPtr->outBufSize = 0;
  1381.     *selectBitsPtr = FS_READABLE | FS_WRITABLE;
  1382.     return(SUCCESS);
  1383. }
  1384.  
  1385. /*
  1386.  *----------------------------------------------------------------------
  1387.  *
  1388.  * PdevDefaultGetAttr --
  1389.  *
  1390.  *    The default GetAttributes handling procedure called when an
  1391.  *    PDEV_GET_ATTR request is received over a request stream.
  1392.  *
  1393.  * Results:
  1394.  *    None.
  1395.  *
  1396.  * Side effects
  1397.  *    None.
  1398.  *
  1399.  *----------------------------------------------------------------------
  1400.  */
  1401. /*ARGSUSED*/
  1402. static int
  1403. PdevDefaultGetAttr(streamPtr, attrPtr, selectBitsPtr)
  1404.     Pdev_Stream *streamPtr;
  1405.     Fs_Attributes *attrPtr;
  1406.     int *selectBitsPtr;
  1407. {
  1408.     bzero((Address)attrPtr, sizeof(Fs_Attributes));
  1409.     attrPtr->fileNumber = (int)streamPtr->clientData;
  1410.     attrPtr->permissions = 0644;
  1411.     attrPtr->type = FS_FILE;
  1412.     *selectBitsPtr = FS_READABLE | FS_WRITABLE;
  1413.     return(SUCCESS);
  1414. }
  1415.  
  1416. /*
  1417.  *----------------------------------------------------------------------
  1418.  *
  1419.  * PdevDefaultSetAttr --
  1420.  *
  1421.  *    The default GetAttributes handling procedure called when an
  1422.  *    PDEV_SET_ATTR request is received over a request stream.
  1423.  *
  1424.  * Results:
  1425.  *    None.
  1426.  *
  1427.  * Side effects
  1428.  *    None.
  1429.  *
  1430.  *----------------------------------------------------------------------
  1431.  */
  1432. /*ARGSUSED*/
  1433. static int
  1434. PdevDefaultSetAttr(streamPtr, flags, uid, gid, attrPtr, selectBitsPtr)
  1435.     Pdev_Stream *streamPtr;
  1436.     int flags;
  1437.     int uid;
  1438.     int gid;
  1439.     Fs_Attributes *attrPtr;
  1440.     int *selectBitsPtr;
  1441. {
  1442.     *selectBitsPtr = FS_READABLE | FS_WRITABLE;
  1443.     return(SUCCESS);
  1444. }
  1445. @
  1446.  
  1447.  
  1448. 1.14
  1449. log
  1450. @free buffers when done with them.
  1451. @
  1452. text
  1453. @d23 1
  1454. a23 1
  1455. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.13 90/05/01 10:19:26 brent Exp Locker: douglis $ SPRITE (Berkeley)";
  1456. d438 1
  1457. a438 1
  1458.         pdevPtr->readBufSize, 0, pdevPtr->defaultService, 0);
  1459. d1163 3
  1460. a1165 2
  1461. PdevDefaultOpen(pdevToken, streamPtr, readBuf, flags, procID, hostID, uid, selectBitsPtr)
  1462.     Pdev_Token pdevToken;    /* Identifies pseudo-device */
  1463. d1220 3
  1464. a1222 8
  1465. PdevDefaultRead(streamPtr, offset, procID, familyID, amountReadPtr, bufferPtr,
  1466.     freeItPtr, selectBitsPtr)
  1467.     Pdev_Stream *streamPtr;        /* Private data */
  1468.     int offset;            /* Byte offset at which to read */
  1469.     int procID;            /* Process ID of calling process */
  1470.     int familyID;        /* Family ID of calling process */
  1471.     int *amountReadPtr;        /* Return - how much data was generated */
  1472.     Address *bufferPtr;        /* Ref. to buffer we fill in with data bytes */
  1473. d1225 1
  1474. d1228 1
  1475. a1228 1
  1476.     *amountReadPtr = 0;
  1477. d1251 2
  1478. a1252 2
  1479. PdevDefaultWrite(streamPtr, async, offset, procID, familyID, numBytesPtr, buffer, selectBitsPtr)
  1480.     Pdev_Stream *streamPtr;        /* Private data */
  1481. d1254 1
  1482. a1254 5
  1483.     int offset;            /* Offset at which to write */
  1484.     int procID;            /* Calling process's ID */
  1485.     int familyID;        /* Calling process's family ID */
  1486.     int *numBytesPtr;        /* In/Out byte count */
  1487.     Address buffer;        /* Buffer containing bytes */
  1488. d1256 1
  1489. d1280 5
  1490. a1284 12
  1491. PdevDefaultIoctl(streamPtr, command, procID, familyID, byteOrder,
  1492.     inSize, inData, outSizePtr, outData, selectBitsPtr)
  1493.     Pdev_Stream *streamPtr;
  1494.     int command;
  1495.     int procID;
  1496.     int familyID;
  1497.     int byteOrder;
  1498.     int inSize;
  1499.     Address inData;
  1500.     int *outSizePtr;
  1501.     Address outData;
  1502.     int *selectBitsPtr;
  1503. d1286 1
  1504. a1286 1
  1505.     *outSizePtr = 0;
  1506. @
  1507.  
  1508.  
  1509. 1.13
  1510. log
  1511. @Fixed selectBits bug.  A GET_ATTR on an open stream that returned
  1512. an error would reset the selectBits to zero.   A SET_ATTR would
  1513. @
  1514. text
  1515. @d23 1
  1516. a23 1
  1517. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.12 90/02/19 14:44:37 douglis Exp Locker: brent $ SPRITE (Berkeley)";
  1518. d386 6
  1519. @
  1520.  
  1521.  
  1522. 1.12
  1523. log
  1524. @added Pdev_GetStreamID, which returns the descriptor hidden behind a 
  1525. Pdev_Token.
  1526. @
  1527. text
  1528. @d23 1
  1529. a23 1
  1530. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.11 90/01/31 08:23:53 ouster Exp Locker: douglis $ SPRITE (Berkeley)";
  1531. d718 1
  1532. a718 1
  1533.         status = PdevDefaultRead(&srvPtr->stream,
  1534. d783 1
  1535. a783 1
  1536.             ReplyNoData(srvPtr, status, 0);
  1537. d803 1
  1538. a803 1
  1539.         ReplyNoData(srvPtr, status, 0);
  1540. @
  1541.  
  1542.  
  1543. 1.11
  1544. log
  1545. @Increase limit on max # of pdevs with same base name from 20 to 100.
  1546. @
  1547. text
  1548. @d23 1
  1549. a23 1
  1550. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.10 89/09/12 14:42:55 brent Exp $ SPRITE (Berkeley)";
  1551. d315 26
  1552. @
  1553.  
  1554.  
  1555. 1.10
  1556. log
  1557. @Removed lint
  1558. @
  1559. text
  1560. @d23 1
  1561. a23 1
  1562. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.9 89/06/02 13:38:23 brent Exp Locker: brent $ SPRITE (Berkeley)";
  1563. d225 1
  1564. a225 1
  1565.     for (i = 1; i < 20; i++) {
  1566. @
  1567.  
  1568.  
  1569. 1.9
  1570. log
  1571. @Updated to new pseudo-device interface with signals
  1572. @
  1573. text
  1574. @d23 1
  1575. a23 1
  1576. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.8 89/04/12 13:33:01 ouster Exp $ SPRITE (Berkeley)";
  1577. a195 1
  1578.     register int op;
  1579. d347 4
  1580. a387 1
  1581.     register ServiceStream *srvPtr;
  1582. d550 1
  1583. d567 1
  1584. d575 9
  1585. a583 2
  1586.         panic("PdevServiceRequest, bad request magic # 0x%x\n",
  1587.                 requestPtr->hdr.magic);
  1588. d612 9
  1589. d662 7
  1590. d691 7
  1591. d729 6
  1592. d748 4
  1593. d770 7
  1594. d936 1
  1595. a936 1
  1596.     if (pdevPtr->stream.magic != PDEV_MAGIC) {
  1597. d978 1
  1598. a978 1
  1599.     if (pdevPtr->stream.magic != PDEV_MAGIC) {
  1600. d1014 1
  1601. a1014 1
  1602.     if (srvPtr->stream.magic != PDEV_STREAM_MAGIC) {
  1603. @
  1604.  
  1605.  
  1606. 1.8
  1607. log
  1608. @Output newline after panic messages.
  1609. @
  1610. text
  1611. @d23 1
  1612. a23 1
  1613. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.7 89/03/20 15:52:26 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  1614. d541 1
  1615. d575 2
  1616. d578 1
  1617. a578 1
  1618.         switch (requestPtr->hdr.operation) {
  1619. d613 1
  1620. a613 1
  1621.          * allow the read procedure to change this buffer.  If it
  1622. d615 2
  1623. a616 1
  1624.          * free the buffer after we reply.
  1625. a617 1
  1626.         char *buffer;
  1627. d637 1
  1628. a637 1
  1629.         buffer = srvPtr->readBuf;
  1630. d639 9
  1631. a647 10
  1632.                 requestPtr->param.read.offset,
  1633.                 requestPtr->param.read.procID,
  1634.                 requestPtr->param.read.familyID,
  1635.                 &reply.replySize,
  1636.                 &buffer, &freeIt,
  1637.                 &reply.selectBits);
  1638.         reply.replyBuf = buffer;
  1639.         ReplyWithData(srvPtr, status, &reply);
  1640.         if (freeIt) {
  1641.             free(buffer);
  1642. a652 2
  1643.         int amountWritten;
  1644.  
  1645. d658 1
  1646. a658 3
  1647.         reply.replySize = sizeof(int);
  1648.         reply.replyBuf = (Address)&amountWritten;
  1649.         amountWritten = requestPtr->hdr.requestSize;
  1650. d661 3
  1651. a663 5
  1652.                 requestPtr->param.read.offset,
  1653.                 requestPtr->param.read.procID,
  1654.                 requestPtr->param.read.familyID,
  1655.                 &amountWritten,    dataPtr,
  1656.                 &reply.selectBits);
  1657. d665 3
  1658. a667 1
  1659.             ReplyWithData(srvPtr, status, &reply);
  1660. d675 6
  1661. d689 6
  1662. d696 2
  1663. a697 9
  1664.         status = (*srvPtr->service->ioctl)(&srvPtr->stream,
  1665.                  requestPtr->param.ioctl.command,
  1666.                  requestPtr->param.ioctl.procID,
  1667.                  requestPtr->param.ioctl.familyID,
  1668.                  requestPtr->param.ioctl.byteOrder,
  1669.                  requestPtr->hdr.requestSize, dataPtr,
  1670.                  &reply.replySize, srvPtr->ioctlOutBuf,
  1671.                  &reply.selectBits);
  1672.         ReplyWithData(srvPtr, status, &reply);
  1673. d711 1
  1674. a711 1
  1675.             ReplyWithData(srvPtr, status, &reply);
  1676. d785 2
  1677. d813 1
  1678. a813 1
  1679. ReplyWithData(srvPtr, status, replyPtr)
  1680. d818 1
  1681. a819 1
  1682.     replyPtr->magic = PDEV_REPLY_MAGIC;
  1683. d825 25
  1684. a849 3
  1685.     replyPtr->status = status;
  1686.     status = Fs_IOControl(srvPtr->stream.streamID, IOC_PDEV_REPLY,
  1687.         sizeof(Pdev_Reply), (Address) replyPtr, 0, (Address) NULL);
  1688. @
  1689.  
  1690.  
  1691. 1.7
  1692. log
  1693. @Wasn't deleting Fs_Dispatch info for control stream.  This delta
  1694. also includes changes made by Brent to make forward references
  1695. "static" instead of "extern".
  1696. @
  1697. text
  1698. @d23 1
  1699. a23 1
  1700. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.6 89/01/26 10:12:54 brent Exp Locker: brent $ SPRITE (Berkeley)";
  1701. d394 1
  1702. a394 1
  1703.     panic("%s; status \"%s\", count %d",
  1704. d399 1
  1705. a399 1
  1706.     panic("%s: %d", "PdevControlRequest got bad notify magic number",
  1707. d555 1
  1708. a555 1
  1709.     panic("%s; status \"%s\", count %d",
  1710. d560 1
  1711. a560 1
  1712.     panic("%s: %d", "PdevServiceRequest got bad pointer magic number",
  1713. d727 1
  1714. a727 1
  1715.         panic("PdevServiceRequest: bad request on request stream: %d",
  1716. d785 1
  1717. a785 1
  1718.     panic("%s; status \"%s\"", "Reply couldn't send pdev reply",
  1719. d824 1
  1720. a824 1
  1721.     panic("%s; status \"%s\"", "ReplyWithData couldn't send pdev reply",
  1722. @
  1723.  
  1724.  
  1725. 1.6
  1726. log
  1727. @Cleaned up the interface and moved Pfs procedures to their own file
  1728. @
  1729. text
  1730. @d23 1
  1731. a23 1
  1732. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.5 89/01/06 07:59:52 brent Exp $ SPRITE (Berkeley)";
  1733. d98 7
  1734. a104 7
  1735. extern int    PdevDefaultOpen();
  1736. extern int    PdevDefaultRead();
  1737. extern int    PdevDefaultWrite();
  1738. extern int    PdevDefaultIoctl();
  1739. extern int    PdevDefaultClose();
  1740. extern int    PdevDefaultGetAttr();
  1741. extern int    PdevDefaultSetAttr();
  1742. d128 5
  1743. a132 5
  1744. extern void    PdevControlRequest();
  1745. extern void    PdevServiceRequest();
  1746. extern int    PdevCleanup();
  1747. extern void    ReplyNoData();
  1748. extern void    ReplyWithData();
  1749. d312 1
  1750. d380 1
  1751. a380 1
  1752. void
  1753. d535 1
  1754. a535 1
  1755. void
  1756. @
  1757.  
  1758.  
  1759. 1.5
  1760. log
  1761. @Added casts for lint
  1762. @
  1763. text
  1764. @d12 1
  1765. a12 1
  1766.  * Copyright 1987 Regents of the University of California
  1767. d23 1
  1768. a23 1
  1769. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/pdev.c,v 1.4 88/11/11 11:30:10 brent Exp $ SPRITE (Berkeley)";
  1770. d44 1
  1771. a44 1
  1772.  * Boolean that can be toggled by applications command line arguments.
  1773. d46 1
  1774. a46 1
  1775. int pdevTrace;
  1776. d49 1
  1777. a49 1
  1778.  * The Server structure is the top-level state for the pseudo-device
  1779. d52 4
  1780. a55 1
  1781.  * procedures for the various pseudo-device operations.
  1782. d58 2
  1783. a59 5
  1784. typedef struct Server {
  1785.     int streamID;        /* Sprite stream identifier for control
  1786.                  * stream for a pseudo-device, or naming
  1787.                  * request-response stream for a
  1788.                  * pseudo-filesystem server. */
  1789. d62 5
  1790. a66 8
  1791.     IntProc *defaultService;    /* Default handlers for pdev operations */
  1792.     /*
  1793.      * The following fields apply only to pseudo-filesystem servers.
  1794.      */
  1795.     ClientData private;        /* Private data passed to callbacks */
  1796.     char *prefix;        /* Pseudo-filesystem prefix */
  1797.     Address requestBuf;        /* Naming connection request buffer */
  1798. } Server;
  1799. d73 2
  1800. a74 1
  1801.     List_Links links;        /* Application streams are linked into a
  1802. d76 2
  1803. a77 2
  1804.                  * terminal. */
  1805.     struct Server *pdevPtr;    /* Server with which this stream is
  1806. d83 10
  1807. a92 8
  1808.                  * pseudo-device by the application.  This
  1809.                  * is optionally used by the server. */
  1810.     IntProc *service;        /* Set of procedures to handle the various
  1811.                  * pseudo-device operations.  If any are
  1812.                  * undefined then the defaults in the
  1813.                  * top-level Server struct are used. */
  1814.     ClientData private;        /* Private to the service procedures.  This
  1815.                  * is set by the service openProc. */
  1816. d95 2
  1817. d98 7
  1818. a104 8
  1819. extern ReturnStatus    PdevDefaultOpen();
  1820. extern ReturnStatus    PdevDefaultRead();
  1821. extern ReturnStatus    PdevDefaultWrite();
  1822. extern ReturnStatus    PdevDefaultIoctl();
  1823. extern ReturnStatus    PdevDefaultClose();
  1824. extern ReturnStatus    PdevDefaultGetAttr();
  1825. extern ReturnStatus    PdevDefaultSetAttr();
  1826. extern ReturnStatus    PfsNullProc();
  1827. d106 8
  1828. a113 19
  1829. static IntProc pdevDefaultProcList[] = {
  1830.     (IntProc)NULL,    /* PDEV_INVALID */
  1831.     PdevDefaultOpen,    /* PDEV_OPEN */
  1832.     (IntProc)NULL,    /* PDEV_DUP */
  1833.     PdevDefaultClose,    /* PDEV_CLOSE */
  1834.     PdevDefaultRead,    /* PDEV_READ */
  1835.     PdevDefaultWrite,    /* PDEV_WRITE */
  1836.     PdevDefaultIoctl,    /* PDEV_IOCTL */
  1837.     PdevDefaultGetAttr,    /* PDEV_GET_ATTR */
  1838.     PdevDefaultSetAttr,    /* PDEV_SET_ATTR */
  1839.     PfsNullProc,    /* PFS_OPEN */
  1840.     PfsNullProc,    /* PFS_GET_ATTR */
  1841.     PfsNullProc,    /* PFS_SET_ATTR */
  1842.     PfsNullProc,    /* PFS_MAKE_DEVICE */
  1843.     PfsNullProc,    /* PFS_MAKE_DIR */
  1844.     PfsNullProc,    /* PFS_REMOVE */
  1845.     PfsNullProc,    /* PFS_REMOVE_DIR */
  1846.     PfsNullProc,    /* PFS_RENAME */
  1847.     PfsNullProc,    /* PFS_HARD_LINK */
  1848. d117 1
  1849. a117 14
  1850.  * There is a default array of handlers associated with the pseudo-device
  1851.  * or the pseudo-filesystem.  Then there is an array of handlers for
  1852.  * each pseudo-device connection.  This macro is used to get a valid
  1853.  * handler for the given operation.
  1854.  */
  1855. #define HANDLER(srvPtr, pdevOp) \
  1856.     ( (srvPtr->service == NULL || srvPtr->service[(int)pdevOp] == NULL) ? \
  1857.         *srvPtr->pdevPtr->defaultService[(int)pdevOp] :          \
  1858.         *srvPtr->service[(int)pdevOp] )
  1859.  
  1860.  
  1861.  
  1862. /*
  1863.  * PDEV_REQUEST_BUF_SIZE     Pseudo-device request buffer size
  1864. d121 2
  1865. a122 3
  1866. #define PDEV_MAX_BYTES    9000
  1867. #define PDEV_REQUEST_BUF_SIZE    (sizeof(Pdev_Request) + PDEV_MAX_BYTES)
  1868. #define PFS_REQUEST_BUF_SIZE    (sizeof(Pfs_Request) + sizeof(Fs2PathData))
  1869. d130 1
  1870. a130 2
  1871. extern void    PfsNamingRequest();
  1872. extern void    PdevCleanup();
  1873. d133 1
  1874. d142 3
  1875. a144 3
  1876.  *    A set of handler procedures for each of the pseudo-device
  1877.  *    operations can be passed in.  If not, then default handlers are
  1878.  *    used.  The set of handlers can be changed with Pdev_SetupHandler.
  1879. d147 2
  1880. a148 2
  1881.  *    The return value is a token for the pseudo-device, which may be
  1882.  *    used in later calls to Pdev_ procedures.  A NULL return value
  1883. d171 2
  1884. a172 2
  1885. ClientData
  1886. Pdev_Open(name, realNamePtr, service)
  1887. d182 5
  1888. a186 7
  1889.     IntProc *service;        /* An array of service procedures that is
  1890.                  * indexed by the Pdev_Op of the request.
  1891.                  * This supplies call-backs for all pdev
  1892.                  * operations that arrive on any pdev
  1893.                  * connection to the pfs server.  This includes
  1894.                  * naming operations on the naming stream,
  1895.                  * and regular operations on other pdev streams.
  1896. d191 1
  1897. d194 1
  1898. a194 1
  1899.     register Server *pdevPtr;
  1900. d212 1
  1901. a212 1
  1902.         return (ClientData) NULL;
  1903. d246 1
  1904. a246 1
  1905.     return (ClientData) NULL;
  1906. d252 1
  1907. a252 1
  1908.         return (ClientData) NULL;
  1909. d259 6
  1910. a264 2
  1911.     pdevPtr = (Server *) malloc(sizeof(Server));
  1912.     pdevPtr->streamID = streamID;
  1913. d266 6
  1914. a271 7
  1915.     pdevPtr->defaultService = (IntProc *)malloc(PDEV_NUM_OPS * sizeof(IntProc));
  1916.     for (op = 0 ; op < PDEV_NUM_OPS ; op++) {
  1917.     if (service == (IntProc *)NULL || service[op] == (IntProc)NULL) {
  1918.         pdevPtr->defaultService[op] = pdevDefaultProcList[op];
  1919.     } else {
  1920.         pdevPtr->defaultService[op] = service[op];
  1921.     }
  1922. a272 1
  1923.  
  1924. d276 1
  1925. a276 1
  1926.     return (ClientData) pdevPtr;
  1927. d299 2
  1928. a300 2
  1929. Pdev_Close(pdev)
  1930.     ClientData    pdev;        /* Token identifying the pseudo-device.
  1931. d303 2
  1932. a304 1
  1933.     register Server *pdevPtr = (Server *) pdev;
  1934. d308 3
  1935. a310 2
  1936.     srvPtr = (ServiceStream *) List_First(&pdevPtr->connectList);
  1937.     PdevCleanup(srvPtr, 0, FALSE);
  1938. d312 2
  1939. a313 2
  1940.     close(pdevPtr->streamID);
  1941.     free((Address)pdev);
  1942. d325 1
  1943. a325 1
  1944.  *    None.
  1945. d328 2
  1946. a329 1
  1947.  *    .
  1948. d334 2
  1949. a335 2
  1950. static void
  1951. PdevCleanup(srvPtr, status, sendReply)
  1952. a336 1
  1953.     ReturnStatus status;        /* Return status from server */
  1954. d340 3
  1955. a342 2
  1956.                      * no reply needed, used in error
  1957.                      * recovery */
  1958. d344 3
  1959. d351 2
  1960. a352 2
  1961.     Fs_EventHandlerDestroy(srvPtr->streamID);
  1962.     close(srvPtr->streamID);
  1963. d354 1
  1964. a354 1
  1965.     if (srvPtr->service != (IntProc *)NULL) {
  1966. d358 1
  1967. a363 26
  1968.  * Pdev_Ready --
  1969.  *
  1970.  *    Indicate that the pseudo-device  is ready for I/O.
  1971.  *
  1972.  * Results:
  1973.  *    The return value of the Fs_IOControl call.
  1974.  *
  1975.  * Side effects:
  1976.  *    Makes an IOC_PDEV_READY IOControl.
  1977.  *
  1978.  *----------------------------------------------------------------------
  1979.  */
  1980.  
  1981. ReturnStatus
  1982. Pdev_Ready(token, selectBits)
  1983.     ClientData    token;        /* Token identifying a stream to the pdev.
  1984.                  * This is passed into the openProc. */
  1985.     int selectBits;        /* FS_READABLE | FS_WRITABLE | FS_EXCEPTION */
  1986. {
  1987.     return(Fs_IOControl((int)token, IOC_PDEV_READY, sizeof(int), &selectBits,
  1988.         0, NULL));
  1989. }
  1990.  
  1991. /*
  1992.  *----------------------------------------------------------------------
  1993.  *
  1994. d368 1
  1995. a368 2
  1996.  *    a new stream is being opened on the pdev;  PdevControlRequest
  1997.  *    handles this.
  1998. d381 1
  1999. a381 1
  2000.     register Server *pdevPtr;    /* Server whose control stream is ready. */
  2001. a385 2
  2002.     Pdev_SetBufArgs setBuf;
  2003.     int false = 0;
  2004. d391 1
  2005. a391 1
  2006.     numBytes = read(pdevPtr->streamID, (char *) ¬ify, sizeof(notify));
  2007. d401 23
  2008. d425 15
  2009. a439 7
  2010.     /*
  2011.      * Set up the service state.  This includes a request buffer used
  2012.      * by the kernel to pass client requests to us.  The procedure list
  2013.      * is set to NULL so we just use the top-level default procedures
  2014.      * for all connections.  A pseudo-filesystem server has more control
  2015.      * than this, see Pfs_Open and Pfs_SetupHandler.
  2016.      */
  2017. d443 53
  2018. a495 5
  2019.     List_Insert(&srvPtr->links, LIST_ATFRONT(&pdevPtr->connectList));
  2020.     srvPtr->streamID = notify.newStreamID;
  2021.     srvPtr->pdevPtr = pdevPtr;
  2022.     srvPtr->service = (IntProc *)NULL;
  2023.     srvPtr->requestBuf = (Address) malloc(PDEV_REQUEST_BUF_SIZE);
  2024. d497 4
  2025. a500 4
  2026.     setBuf.requestBufSize = PDEV_REQUEST_BUF_SIZE;
  2027.     setBuf.readBufAddr = NULL;
  2028.     setBuf.readBufSize = 0;
  2029.     Fs_IOControl(srvPtr->streamID, IOC_PDEV_WRITE_BEHIND,
  2030. d502 1
  2031. a502 1
  2032.     Fs_IOControl(srvPtr->streamID, IOC_PDEV_SET_BUF,
  2033. d505 4
  2034. a508 1
  2035.     Fs_EventHandlerCreate(notify.newStreamID, FS_READABLE, PdevServiceRequest,
  2036. d510 2
  2037. d544 1
  2038. a544 1
  2039.     ReturnStatus status;
  2040. d551 2
  2041. a552 1
  2042.     numBytes = read(srvPtr->streamID, (char *) &bufPtrs, sizeof(Pdev_BufPtrs));
  2043. d574 2
  2044. a575 2
  2045.     switch (requestPtr->hdr.operation) {
  2046.         case PDEV_OPEN:
  2047. d581 4
  2048. a584 2
  2049.         if (pdevTrace) {
  2050.             printf("OPEN %d: uid %d use %x", srvPtr->streamID,
  2051. d588 4
  2052. a591 2
  2053.         status = (HANDLER(srvPtr, PDEV_OPEN))
  2054.                 ((ClientData)srvPtr->streamID,
  2055. d596 1
  2056. a596 1
  2057.                 &srvPtr->private, &selectBits);
  2058. d599 1
  2059. d601 2
  2060. a602 2
  2061.         if (pdevTrace) {
  2062.             printf("CLOSE %d", srvPtr->streamID);
  2063. d604 1
  2064. a604 2
  2065.         status = (HANDLER(srvPtr, PDEV_CLOSE))(srvPtr->private);
  2066.         PdevCleanup(srvPtr, status, TRUE);
  2067. a612 1
  2068.         char readBuf[FS_BLOCK_SIZE];
  2069. d616 2
  2070. a617 2
  2071.         if (pdevTrace) {
  2072.             printf("READ %d bytes at offset %d\n",
  2073. d623 9
  2074. a631 5
  2075.         if (reply.replySize > FS_BLOCK_SIZE) {
  2076.             buffer = malloc(reply.replySize);
  2077.             freeIt = TRUE;
  2078.         } else {
  2079.             buffer = readBuf;
  2080. d633 2
  2081. a634 1
  2082.         status = (HANDLER(srvPtr, PDEV_READ))(srvPtr->private,
  2083. d636 1
  2084. d648 1
  2085. d652 2
  2086. a653 2
  2087.         if (pdevTrace) {
  2088.             printf("WRITE %d bytes at offset %d",
  2089. d660 2
  2090. a661 1
  2091.         status = (HANDLER(srvPtr, PDEV_WRITE))(srvPtr->private,
  2092. d663 1
  2093. d667 3
  2094. a669 1
  2095.         ReplyWithData(srvPtr, status, &reply);
  2096. d673 2
  2097. a674 5
  2098.         char outBuf[FS_BLOCK_SIZE];
  2099.         char *buffer;
  2100.  
  2101.         if (pdevTrace) {
  2102.             printf("IOCTL %d", requestPtr->param.ioctl.command);
  2103. d677 6
  2104. a682 4
  2105.         if (reply.replySize > FS_BLOCK_SIZE) {
  2106.             buffer = malloc(reply.replySize);
  2107.         } else {
  2108.             buffer = outBuf;
  2109. d684 2
  2110. a685 2
  2111.         reply.replyBuf = buffer;
  2112.         status = (HANDLER(srvPtr, PDEV_IOCTL))(srvPtr->private,
  2113. d687 1
  2114. a688 1
  2115. #ifdef ok_to_compile
  2116. a689 1
  2117. #endif ok_to_compile
  2118. d691 1
  2119. a691 1
  2120.                  &reply.replySize, buffer,
  2121. a693 3
  2122.         if (buffer != outBuf) {
  2123.             free(buffer);
  2124.         }
  2125. d699 2
  2126. a700 2
  2127.         if (pdevTrace) {
  2128.             printf("GET ATTR");
  2129. d702 1
  2130. a702 1
  2131.         status = (HANDLER(srvPtr, PDEV_GET_ATTR))(srvPtr->private,
  2132. d714 2
  2133. a715 2
  2134.         if (pdevTrace) {
  2135.             printf("SET ATTR %x", requestPtr->param.setAttr.flags);
  2136. d717 1
  2137. a717 1
  2138.         status = (HANDLER(srvPtr, PDEV_SET_ATTR))(srvPtr->private,
  2139. d729 2
  2140. a730 2
  2141.     if (pdevTrace) {
  2142.         printf(" Returns %x\n", status);
  2143. d733 1
  2144. a733 1
  2145.      * Tell the kernel we removed a request and see if there are any more.
  2146. a735 3
  2147.     Fs_IOControl(srvPtr->streamID, IOC_PDEV_SET_PTRS,
  2148.             sizeof(Pdev_BufPtrs), (Address)&bufPtrs,
  2149.             0, (Address) NULL);
  2150. d737 6
  2151. d748 1
  2152. a748 1
  2153.  * Pfs_Open --
  2154. d750 3
  2155. a752 5
  2156.  *    Establish a pseudo-filesystem server with a given set of handler
  2157.  *    procedures both for the naming operations to the pseudo-filesystem,
  2158.  *    and for the I/O operations on pseudo-device connections established
  2159.  *    inside the pseudo-filesystem.
  2160.  * 
  2161. d754 1
  2162. a754 2
  2163.  *    An opaque pointer to some state so the handlers for
  2164.  *    various pseudo-device operations can be re-defined.
  2165. d757 2
  2166. a758 1
  2167.  *    Opens the pseudo-filesystem.  Sets up a call-back.
  2168. d762 6
  2169. a767 7
  2170. ClientData
  2171. Pfs_Open(prefix, private, service)
  2172.     char *prefix;        /* Prefix of the pseudo-filesystem */
  2173.     ClientData private;        /* Private data passed to callbacks */
  2174.     IntProc *service;        /* Array of callback procedures.  Can be NULL,
  2175.                  * or individual elements can be NULL, to
  2176.                  * get default callbacks. */
  2177. d769 1
  2178. a769 5
  2179.     int namingFD;
  2180.     register Server *pfsPtr;
  2181.     register int op;
  2182.     Pdev_SetBufArgs setBuf;
  2183.     ReturnStatus status;
  2184. d771 6
  2185. a776 5
  2186.     namingFD = open(prefix, O_PFS_MASTER|O_RDONLY, 0);
  2187.     if (namingFD < 0) {
  2188.     fprintf(stderr, "Pfs_Open: ");
  2189.     perror(prefix);
  2190.     return((ClientData)NULL);
  2191. d778 5
  2192. a782 22
  2193.  
  2194.     pfsPtr = (Server *)malloc(sizeof(Server));
  2195.     pfsPtr->streamID = namingFD;
  2196.     List_Init(&pfsPtr->connectList);
  2197.     pfsPtr->defaultService = (IntProc *)malloc(PDEV_NUM_OPS * sizeof(IntProc));
  2198.     for (op = 0 ; op < PDEV_NUM_OPS ; op++) {
  2199.     if (service == (IntProc *)NULL || service[op] == (IntProc)NULL) {
  2200.         pfsPtr->defaultService[op] = pdevDefaultProcList[op];
  2201.     } else {
  2202.         pfsPtr->defaultService[op] = service[op];
  2203.     }
  2204.     }
  2205.  
  2206.     pfsPtr->prefix = prefix;
  2207.     pfsPtr->private = private;
  2208.     pfsPtr->requestBuf = (Address)malloc(PFS_REQUEST_BUF_SIZE);
  2209.     setBuf.requestBufAddr = pfsPtr->requestBuf;
  2210.     setBuf.requestBufSize = PFS_REQUEST_BUF_SIZE;
  2211.     setBuf.readBufAddr = NULL;
  2212.     setBuf.readBufSize = 0;
  2213.     status = Fs_IOControl(namingFD, IOC_PDEV_SET_BUF, sizeof(Pdev_SetBufArgs),
  2214.         (Address)&setBuf, 0, (Address) NULL);
  2215. d784 2
  2216. a785 3
  2217.     printf("IOC_PDEV_SET_BUF failed <%x>\n", status);
  2218.     close(namingFD);
  2219.     return((ClientData)NULL);
  2220. a786 5
  2221.  
  2222.     Fs_EventHandlerCreate(namingFD, FS_READABLE, PfsNamingRequest,
  2223.                 (ClientData)pfsPtr);
  2224.  
  2225.     return((ClientData)pfsPtr);
  2226. d792 1
  2227. a792 1
  2228.  * Pfs_SetHandler --
  2229. d794 2
  2230. a795 3
  2231.  *    Set a handler for a particular PFS request.  If the handler is
  2232.  *    NULL then a default procedure replaces the existing handler.
  2233.  * 
  2234. d800 2
  2235. a801 1
  2236.  *    Updates the top-level callback list, the one used for naming requests.
  2237. d805 7
  2238. a811 5
  2239. void
  2240. Pfs_SetHandler(pfsToken, operation, handler)
  2241.     ClientData pfsToken;    /* Return value from Pfs_Open */
  2242.     Pdev_Op operation;        /* Which operation to set the handler for */
  2243.     IntProc handler;        /* The callback procedure */
  2244. d813 3
  2245. a815 8
  2246.     register Server *pfsPtr = (Server *)pfsToken;
  2247.  
  2248.     if ((int)operation < 0 || (int)operation > PDEV_NUM_OPS) {
  2249.     return;
  2250.     }
  2251.     if (handler == (IntProc)NULL) {
  2252.     pfsPtr->defaultService[(int)operation] =
  2253.         pdevDefaultProcList[(int)operation];
  2254. d817 1
  2255. a817 1
  2256.     pfsPtr->defaultService[(int)operation] = handler;
  2257. d819 7
  2258. d831 1
  2259. a831 1
  2260.  * PfsNamingRequest --
  2261. d833 2
  2262. a834 4
  2263.  *    Called when the naming request-response stream has a new request.
  2264.  *    This makes a call-back to the corresponding procedure in the
  2265.  *    defaultService list kept state for the pseudo-filesystem.
  2266.  * 
  2267. d836 3
  2268. a838 1
  2269.  *    None.
  2270. d841 1
  2271. a841 1
  2272.  *    Calls the users handler for the naming operation.
  2273. d845 5
  2274. a849 3
  2275. /*ARGSUSED*/
  2276. void
  2277. PfsNamingRequest(clientData, streamID, eventMask)
  2278. a850 2
  2279.     int streamID;
  2280.     int eventMask;
  2281. d852 4
  2282. a855 11
  2283.     register Server *pfsPtr = (Server *)clientData;
  2284.     Pdev_BufPtrs bufPtrs;
  2285.     Pfs_Request *requestPtr;
  2286.     Pdev_Reply reply;
  2287.     int numBytes;
  2288.     Address dataPtr;
  2289.     ReturnStatus status;
  2290.     int replySize;
  2291.     Address replyBuf;
  2292.     FsRedirectInfo redirectInfo;
  2293.     Fs2PathRedirectInfo redirect2Info;
  2294. d857 3
  2295. a859 2
  2296.     if (pdevTrace) {
  2297.     printf("<%s> ", pfsPtr->prefix);
  2298. d861 6
  2299. a866 10
  2300.  
  2301.     /*
  2302.      * Read the current pointers for the request buffer.
  2303.      */
  2304.  
  2305.     numBytes = read(streamID, (char *) &bufPtrs, sizeof(Pdev_BufPtrs));
  2306.     if (numBytes != sizeof(Pdev_BufPtrs)) {
  2307.     panic("%s; status \"%s\", count %d",
  2308.         "PfsNamingRequest had trouble reading request buffer pointers",
  2309.         strerror(errno), numBytes);
  2310. d868 2
  2311. a869 15
  2312.     if (bufPtrs.magic != PDEV_BUF_PTR_MAGIC) {
  2313.     panic("%s: %d", "PfsNamingRequest got bad pointer magic number",
  2314.         bufPtrs.magic);
  2315.     }
  2316.     /*
  2317.      * While there are still requests in the buffer, service them.
  2318.      */
  2319.     while (bufPtrs.requestFirstByte < bufPtrs.requestLastByte) {
  2320.     requestPtr =
  2321.         (Pfs_Request *)&pfsPtr->requestBuf[bufPtrs.requestFirstByte];
  2322.     if (requestPtr->hdr.magic != PFS_REQUEST_MAGIC) {
  2323.         panic("PfsNamingRequest, bad request magic # 0x%x\n",
  2324.                 requestPtr->hdr.magic);
  2325.     }
  2326.     dataPtr = (Address)((int)requestPtr + sizeof(Pfs_Request));
  2327. d871 27
  2328. a897 7
  2329.     status = FS_FILE_NOT_FOUND;
  2330.     replySize = 0;
  2331.     replyBuf = NULL;
  2332.     switch (requestPtr->hdr.operation) {
  2333.         case PFS_OPEN: {
  2334.         register char *name;
  2335.         FsOpenArgs *openArgsPtr;
  2336. d899 3
  2337. a901 181
  2338.         name = (char *)dataPtr;
  2339.         openArgsPtr = &requestPtr->param.open;
  2340.         if (pdevTrace) {
  2341.             printf("OPEN %s: uid %d gid %d use %x cwd <%d,%d,%x,%x>",
  2342.             name, openArgsPtr->id.user, openArgsPtr->id.group[0],
  2343.             openArgsPtr->useFlags,
  2344.             openArgsPtr->prefixID.serverID,
  2345.             openArgsPtr->prefixID.type, openArgsPtr->prefixID.major,
  2346.             openArgsPtr->prefixID.minor);
  2347.         }
  2348.         status = (*pfsPtr->defaultService[(int)PFS_OPEN])(pfsPtr->private,
  2349.                 name, openArgsPtr, (ClientData)pfsPtr,
  2350.                 &redirectInfo);
  2351.         if (status == SUCCESS) {
  2352.             /*
  2353.              * The openProc has already replied.
  2354.              */
  2355.             if (pdevTrace) {
  2356.             printf(" Returns OK\n");
  2357.             }
  2358.             goto nextMsg;
  2359.         }
  2360.         break;
  2361.         }
  2362.         case PFS_GET_ATTR: {
  2363.         register char *name;
  2364.         Fs_Attributes attr;
  2365.  
  2366.         name = (char *)dataPtr;
  2367.  
  2368.         if (pdevTrace) {
  2369.             printf("GET_ATTR %s", name);
  2370.         }
  2371.         status = (*pfsPtr->defaultService[(int)PFS_GET_ATTR])
  2372.             (pfsPtr->private, name, &requestPtr->param.open, &attr,
  2373.             &redirectInfo);
  2374.         if (status == SUCCESS) {
  2375.             replyBuf = (Address)&attr;
  2376.             replySize = sizeof(Fs_Attributes);
  2377.         }
  2378.         break;
  2379.         }
  2380.         case PFS_SET_ATTR: {
  2381.         register Pfs_SetAttrData *setAttrPtr =
  2382.             (Pfs_SetAttrData *)dataPtr;
  2383.  
  2384.         if (pdevTrace) {
  2385.             printf("SET_ATTR %s: ", setAttrPtr->name);
  2386.             printf("client %d uid %d gid %d: ",
  2387.             requestPtr->param.open.clientID,
  2388.             requestPtr->param.open.id.user,
  2389.             requestPtr->param.open.id.group[0]);
  2390.             if (setAttrPtr->flags & FS_SET_TIMES) {
  2391.             printf("(access = %d) (modify = %d) ",
  2392.                 setAttrPtr->attr.accessTime.seconds,
  2393.                 setAttrPtr->attr.dataModifyTime.seconds);
  2394.             }
  2395.             if (setAttrPtr->flags & FS_SET_MODE) {
  2396.             printf("(mode = 0%o) ", setAttrPtr->attr.permissions);
  2397.             }
  2398.             if (setAttrPtr->flags & FS_SET_OWNER) {
  2399.             printf("(uid = %d) (gid = %d) ", setAttrPtr->attr.uid,
  2400.                     setAttrPtr->attr.gid);
  2401.             }
  2402.             if (setAttrPtr->flags & FS_SET_FILE_TYPE) {
  2403.             printf("(userType = %d) ", setAttrPtr->attr.userType);
  2404.             }
  2405.             if (setAttrPtr->flags & FS_SET_DEVICE) {
  2406.             printf("(device = <%d,%d,%d>) ",
  2407.                 setAttrPtr->attr.devServerID,
  2408.                 setAttrPtr->attr.devType,
  2409.                 setAttrPtr->attr.devUnit);
  2410.             }
  2411.         }
  2412.         status = (*pfsPtr->defaultService[(int)PFS_SET_ATTR])
  2413.             (pfsPtr->private, setAttrPtr->name,
  2414.              &requestPtr->param.open, setAttrPtr->flags,
  2415.              &setAttrPtr->attr, &redirectInfo);
  2416.         break;
  2417.         }
  2418.         case PFS_MAKE_DEVICE: {
  2419.         register char *name;
  2420.  
  2421.         name = (char *)dataPtr;
  2422.         if (pdevTrace) {
  2423.             printf("MAKE_DEVICE %s: <%d,%d,%d>", name,
  2424.             requestPtr->param.makeDevice.device.serverID,
  2425.             requestPtr->param.makeDevice.device.type,
  2426.             requestPtr->param.makeDevice.device.unit);
  2427.         }
  2428.         status = (*pfsPtr->defaultService[(int)PFS_MAKE_DEVICE])
  2429.             (pfsPtr->private, name, &requestPtr->param.makeDevice,
  2430.             &redirectInfo);
  2431.         break;
  2432.         }
  2433.         case PFS_MAKE_DIR: {
  2434.         register char *name;
  2435.  
  2436.         name = (char *)dataPtr; 
  2437.         if (pdevTrace) {
  2438.             printf("MAKE_DIR %s", name);
  2439.         }
  2440.         status = (*pfsPtr->defaultService[(int)PFS_MAKE_DIR])
  2441.             (pfsPtr->private, name, &requestPtr->param.open,
  2442.             &redirectInfo);
  2443.         break;
  2444.         }
  2445.         case PFS_REMOVE: {
  2446.         register char *name;
  2447.  
  2448.         name = (char *)dataPtr;
  2449.         if (pdevTrace) {
  2450.             printf("REMOVE %s", name);
  2451.         }
  2452.         status = (*pfsPtr->defaultService[(int)PFS_REMOVE])
  2453.                 (pfsPtr->private, name, &requestPtr->param.lookup,
  2454.                 &redirectInfo);
  2455.         break;
  2456.         }
  2457.         case PFS_REMOVE_DIR: {
  2458.         register char *name;
  2459.  
  2460.         name = (char *)dataPtr;
  2461.         if (pdevTrace) {
  2462.             printf("REMOVE %s", name);
  2463.         }
  2464.         status = (*pfsPtr->defaultService[(int)PFS_REMOVE_DIR])
  2465.             (pfsPtr->private, name, &requestPtr->param.lookup,
  2466.             &redirectInfo);
  2467.         break;
  2468.         }
  2469.         case PFS_HARD_LINK:
  2470.         case PFS_RENAME: {
  2471.         register Fs2PathData *pathsPtr;
  2472.  
  2473.         pathsPtr = (Fs2PathData *)dataPtr;
  2474.         if (pdevTrace) {
  2475.             printf("%s %s %s", 
  2476.             (requestPtr->hdr.operation == PFS_RENAME) ? "RENAME" :
  2477.             "HARD LINK", pathsPtr->path1, pathsPtr->path2);
  2478.         }
  2479.         status = (*pfsPtr->defaultService[(int)requestPtr->hdr.operation])
  2480.             (pfsPtr->private, pathsPtr->path1, pathsPtr->path2,
  2481.             &requestPtr->param.rename, &redirect2Info);
  2482.         break;
  2483.         }
  2484.         default:
  2485.         panic("PfsNamingRequest: bad request on request stream: %d",
  2486.             requestPtr->hdr.operation);
  2487.     }
  2488.     if (status == FS_LOOKUP_REDIRECT) {
  2489.         if (requestPtr->hdr.operation == PFS_RENAME ||
  2490.         requestPtr->hdr.operation == PFS_HARD_LINK) {
  2491.         replyBuf = (Address)&redirect2Info;
  2492.         replySize = sizeof(Fs2PathRedirectInfo);
  2493.         } else {
  2494.         replyBuf = (Address)&redirectInfo;
  2495.         replySize = sizeof(FsRedirectInfo);
  2496.         }
  2497.     }
  2498.     if (pdevTrace) {
  2499.         printf(" Returns %x\n", status);
  2500.     }
  2501.     reply.magic = PDEV_REPLY_MAGIC;
  2502.     reply.status = status;
  2503.     reply.replyBuf = replyBuf;
  2504.     reply.replySize = replySize;
  2505.     reply.selectBits = 0;
  2506.     status = Fs_IOControl(streamID, IOC_PDEV_REPLY,
  2507.         sizeof(Pdev_Reply), (Address) &reply, 0, (Address) NULL);
  2508.     if (status != SUCCESS) {
  2509.         fprintf(stderr, "IOC_PDEV_REPLY status 0x%x\n", status);
  2510.     }
  2511.     /*
  2512.      * Tell the kernel we removed a request and see if there are any more.
  2513.      */
  2514. nextMsg:
  2515.     bufPtrs.requestFirstByte += requestPtr->hdr.messageSize;
  2516.     (void)Fs_IOControl(streamID, IOC_PDEV_SET_PTRS,
  2517.             sizeof(Pdev_BufPtrs), (Address)&bufPtrs,
  2518.             0, (Address) NULL);
  2519. d904 2
  2520. d911 1
  2521. a911 1
  2522.  * Pfs_OpenConnection --
  2523. d913 4
  2524. a916 5
  2525.  *    Called to open a new pdev connection in response to an PFS_OPEN
  2526.  *    request.  This does an IOC_PFS_OPEN to set up the connection, and
  2527.  *    the sets up a call-back to PdevServiceRequest to handle the subsequent
  2528.  *    operations on the new connection.  The pdev handlers are the
  2529.  *    default ones until updated with Pdev_SetupHandler.
  2530. d919 1
  2531. a919 1
  2532.  *    None.
  2533. d922 1
  2534. a922 1
  2535.  *    Turns off tracing, etc.
  2536. d926 5
  2537. a930 6
  2538. ReturnStatus
  2539. Pfs_OpenConnection(token, fileIDPtr, service, private)
  2540.     ClientData token;        /* Ref. to Server state */
  2541.     Fs_FileID *fileIDPtr;    /* Server's name for this connection */
  2542.     IntProc *service;        /* Set of handlers for this pdev connection */
  2543.     ClientData private;        /* Private data passed to pdev call-backs */
  2544. d932 2
  2545. a933 6
  2546.     int newStreamID;
  2547.     register Server *pfsPtr = (Server *)token;
  2548.     register ServiceStream *srvPtr;
  2549.     Pdev_SetBufArgs setBuf;
  2550.     int selectBits;
  2551.     ReturnStatus status;
  2552. d935 3
  2553. a937 5
  2554.     status = Fs_IOControl(pfsPtr->streamID, IOC_PFS_OPEN, sizeof(Fs_FileID),
  2555.         (Address)fileIDPtr, sizeof(int), (Address)&newStreamID);
  2556.     if (status != SUCCESS) {
  2557.     fprintf(stderr, "IOC_PFS_OPEN failed <%x>\n", status);
  2558.     return(status);
  2559. a938 10
  2560.     /*
  2561.      * Allocate state for the new pseudo-device connection
  2562.      */
  2563.     srvPtr = (ServiceStream *)malloc(sizeof(ServiceStream));
  2564.     List_InitElement(&srvPtr->links);
  2565.     List_Insert(&srvPtr->links, LIST_ATFRONT(&pfsPtr->connectList));
  2566.     srvPtr->pdevPtr = pfsPtr;
  2567.     srvPtr->streamID = newStreamID;
  2568.     srvPtr->requestBuf = (Address)malloc(PDEV_REQUEST_BUF_SIZE);
  2569.     srvPtr->readBuf = NULL;
  2570. d940 2
  2571. a941 35
  2572.     if (service == (IntProc *)NULL) {
  2573.     srvPtr->service = NULL;
  2574.     } else {
  2575.     register int op;
  2576.     srvPtr->service = (IntProc *)malloc(PDEV_NUM_OPS * sizeof(IntProc));
  2577.     for (op = 0 ; op < PDEV_NUM_OPS ; op++) {
  2578.         srvPtr->service[op] = service[op];
  2579.     }
  2580.     }
  2581.     srvPtr->private = private;
  2582.  
  2583.     /*
  2584.      * Allocate request buffer and tell the kernel about it.
  2585.      */
  2586.     setBuf.requestBufAddr = srvPtr->requestBuf;
  2587.     setBuf.requestBufSize = PDEV_REQUEST_BUF_SIZE;
  2588.     setBuf.readBufAddr = NULL;
  2589.     setBuf.readBufSize = 0;
  2590.     status = Fs_IOControl(newStreamID, IOC_PDEV_SET_BUF,
  2591.         sizeof(Pdev_SetBufArgs), (Address)&setBuf, 0, (Address) NULL);
  2592.     if (status != SUCCESS) {
  2593.     printf("IOC_PDEV_SET_BUF failed <%x>\n", status);
  2594.     close(newStreamID);
  2595.     }
  2596.     selectBits = FS_READABLE|FS_WRITABLE;
  2597.     status = Fs_IOControl(newStreamID, IOC_PDEV_READY,
  2598.         sizeof(int), (Address)&selectBits, 0, (Address) NULL);
  2599.     if (status != SUCCESS) {
  2600.     printf("IOC_PDEV_READY failed <%x>\n", status);
  2601.     close(newStreamID);
  2602.     }
  2603.  
  2604.     Fs_EventHandlerCreate(newStreamID, FS_READABLE, PdevServiceRequest,
  2605.                 (ClientData)srvPtr);
  2606.     return(SUCCESS);
  2607. d947 1
  2608. a947 1
  2609.  * PfsNullProc --
  2610. d949 2
  2611. a950 1
  2612.  *    Do-nothing callback.
  2613. d953 1
  2614. a953 1
  2615.  *    Returns FS_FILE_NOT_FOUND.
  2616. d956 1
  2617. a956 1
  2618.  *    None.
  2619. d960 6
  2620. a965 2
  2621. static ReturnStatus
  2622. PfsNullProc()
  2623. d967 65
  2624. a1031 1
  2625.     return(FS_FILE_NOT_FOUND);
  2626. d1051 5
  2627. a1055 3
  2628. static ReturnStatus
  2629. PdevDefaultOpen(token, flags, pid, hostID, uid, privatePtr, selectBitsPtr)
  2630.     ClientData token;        /* Identifies open stream */
  2631. d1057 1
  2632. a1057 1
  2633.     int pid;            /* Process ID doing the open */
  2634. a1059 1
  2635.     ClientData *privatePtr;    /* Return - private data (not used) */
  2636. a1061 1
  2637.     *privatePtr = (ClientData)NULL;
  2638. d1083 3
  2639. a1085 3
  2640. static ReturnStatus
  2641. PdevDefaultClose(private)
  2642.     ClientData private;
  2643. d1107 4
  2644. a1110 4
  2645. static ReturnStatus
  2646. PdevDefaultRead(private, offset, familyID, amountReadPtr, bufferPtr, freeItPtr,
  2647.         selectBitsPtr)
  2648.     ClientData private;        /* Private data */
  2649. d1112 1
  2650. d1116 1
  2651. a1116 1
  2652.     Boolean *freeItPtr;        /* In/Out indicates if *bufferPtr is malloc'd */
  2653. d1119 1
  2654. d1142 4
  2655. a1145 3
  2656. static ReturnStatus
  2657. PdevDefaultWrite(private, offset, familyID, numBytesPtr, buffer, selectBitsPtr)
  2658.     ClientData private;        /* Private data */
  2659. d1147 1
  2660. d1174 4
  2661. a1177 3
  2662. static ReturnStatus
  2663. PdevDefaultIoctl(private, command, familyID, inSize, inData, outSizePtr, outData, selectBitsPtr)
  2664.     ClientData private;
  2665. d1179 1
  2666. d1181 1
  2667. d1210 3
  2668. a1212 3
  2669. static ReturnStatus
  2670. PdevDefaultGetAttr(private, attrPtr, selectBitsPtr)
  2671.     ClientData private;
  2672. d1217 1
  2673. a1217 1
  2674.     attrPtr->fileNumber = (int)private;
  2675. d1241 3
  2676. a1243 3
  2677. static ReturnStatus
  2678. PdevDefaultSetAttr(private, flags, uid, gid, attrPtr, selectBitsPtr)
  2679.     ClientData private;
  2680. a1251 73
  2681. }
  2682.  
  2683. /*
  2684.  *----------------------------------------------------------------------
  2685.  *
  2686.  * ReplyNoData --
  2687.  *
  2688.  *    Send a reply back with no data;  just a return status.  This
  2689.  *    procedure is most often used for error returns.
  2690.  *
  2691.  * Results:
  2692.  *    None.
  2693.  *
  2694.  * Side effects:
  2695.  *    The application will receive status as the return from the
  2696.  *    system call it invoked.
  2697.  *
  2698.  *----------------------------------------------------------------------
  2699.  */
  2700.  
  2701. static void
  2702. ReplyNoData(srvPtr, status, selectBits)
  2703.     ServiceStream *srvPtr;    /* Application stream info. */
  2704.     ReturnStatus status;    /* Error code to send to application. */
  2705.     int selectBits;        /* Current select state for the stream */
  2706. {
  2707.     Pdev_Reply reply;
  2708.  
  2709.     reply.magic = PDEV_REPLY_MAGIC;
  2710.     reply.selectBits = selectBits;
  2711.     reply.status = status;
  2712.     reply.replySize = 0;
  2713.     reply.replyBuf = NULL;
  2714.     status = Fs_IOControl(srvPtr->streamID, IOC_PDEV_REPLY,
  2715.         sizeof(Pdev_Reply), (Address) &reply, 0, (Address) NULL);
  2716.     if (status != SUCCESS) {
  2717.     panic("%s; status \"%s\"", "Reply couldn't send pdev reply",
  2718.         Stat_GetMsg(status));
  2719.     }
  2720. }
  2721.  
  2722. /*
  2723.  *----------------------------------------------------------------------
  2724.  *
  2725.  * ReplyWithData --
  2726.  *
  2727.  *    Send a reply back along with some data.
  2728.  *
  2729.  * Results:
  2730.  *    None.
  2731.  *
  2732.  * Side effects:
  2733.  *    The application will receive status as the return from the
  2734.  *    system call it invoked.
  2735.  *
  2736.  *----------------------------------------------------------------------
  2737.  */
  2738.  
  2739. static void
  2740. ReplyWithData(srvPtr, status, replyPtr)
  2741.     ServiceStream *srvPtr;    /* Application stream info. */
  2742.     ReturnStatus status;    /* Error code to send to application. */
  2743.     Pdev_Reply *replyPtr;    /* Partially completed reply.  The replySize,
  2744.                  * data area, and selectBits should be set. */
  2745. {
  2746.     replyPtr->magic = PDEV_REPLY_MAGIC;
  2747.     replyPtr->status = status;
  2748.     status = Fs_IOControl(srvPtr->streamID, IOC_PDEV_REPLY,
  2749.         sizeof(Pdev_Reply), (Address) replyPtr, 0, (Address) NULL);
  2750.     if (status != SUCCESS) {
  2751.     panic("%s; status \"%s\"", "ReplyWithData couldn't send pdev reply",
  2752.         Stat_GetMsg(status));
  2753.     }
  2754. @
  2755.  
  2756.  
  2757. 1.4
  2758. log
  2759. @Added pseudo-filesystem support
  2760. Extensively changed the call-back setup.
  2761. @
  2762. text
  2763. @d23 1
  2764. a23 1
  2765. static char rcsid[] = "$Header: pdev.c,v 1.2 88/08/29 13:00:07 brent Exp $ SPRITE (Berkeley)";
  2766. a102 1
  2767. extern ReturnStatus    PdevNullProc();
  2768. d133 3
  2769. a135 3
  2770.     ( (srvPtr->service == NULL || srvPtr->service[pdevOp] == NULL) ?    \
  2771.         *srvPtr->pdevPtr->defaultService[pdevOp] :            \
  2772.         *srvPtr->service[pdevOp] )
  2773. a499 1
  2774.     register Server *pdevPtr = srvPtr->pdevPtr;
  2775. d635 3
  2776. d790 1
  2777. a790 1
  2778.     if (operation < 0 || operation > PDEV_NUM_OPS) {
  2779. d794 2
  2780. a795 1
  2781.     pfsPtr->defaultService[operation] = pdevDefaultProcList[operation];
  2782. d797 1
  2783. a797 1
  2784.     pfsPtr->defaultService[operation] = handler;
  2785. a833 1
  2786.     Fs_Attributes attr;
  2787. d885 1
  2788. a885 1
  2789.         status = (*pfsPtr->defaultService[PFS_OPEN])(pfsPtr->private,
  2790. d908 1
  2791. a908 1
  2792.         status = (*pfsPtr->defaultService[PFS_GET_ATTR])
  2793. d949 1
  2794. a949 1
  2795.         status = (*pfsPtr->defaultService[PFS_SET_ATTR])
  2796. d965 1
  2797. a965 1
  2798.         status = (*pfsPtr->defaultService[PFS_MAKE_DEVICE])
  2799. d977 1
  2800. a977 1
  2801.         status = (*pfsPtr->defaultService[PFS_MAKE_DIR])
  2802. d989 1
  2803. a989 1
  2804.         status = (*pfsPtr->defaultService[PFS_REMOVE])
  2805. d1001 1
  2806. a1001 1
  2807.         status = (*pfsPtr->defaultService[PFS_REMOVE_DIR])
  2808. d1016 1
  2809. a1016 1
  2810.         status = (*pfsPtr->defaultService[requestPtr->hdr.operation])
  2811. a1143 21
  2812.     return(SUCCESS);
  2813. }
  2814.  
  2815. /*
  2816.  *----------------------------------------------------------------------
  2817.  *
  2818.  * PdevNullProc --
  2819.  *
  2820.  *    Do-nothing callback.
  2821.  *
  2822.  * Results:
  2823.  *    Returns SUCCESS.
  2824.  *
  2825.  * Side effects:
  2826.  *    None.
  2827.  *
  2828.  *----------------------------------------------------------------------
  2829.  */
  2830. static ReturnStatus
  2831. PdevNullProc()
  2832. {
  2833. @
  2834.  
  2835.  
  2836. 1.3
  2837. log
  2838. @Updated to new pseudo-device declarations
  2839. @
  2840. text
  2841. @d30 1
  2842. a30 1
  2843. #include <dev/pdev.h>
  2844. d44 1
  2845. a44 3
  2846.  * The structure below corresponds to an application's stream.  There's
  2847.  * one of these for each open that involves a pseudo-device for which
  2848.  * this module is the server.
  2849. d46 1
  2850. d48 27
  2851. d87 4
  2852. a94 5
  2853. /*
  2854.  * The structure below corresponds to one terminal (one call to Pdev_Open).
  2855.  * It maintains our state about the terminal, including stuff like the
  2856.  * input buffer and pointers to each of the open streams on the terminal.
  2857.  */
  2858. d96 9
  2859. a104 11
  2860. typedef struct Server {
  2861.     int streamID;        /* Sprite stream identifier for control
  2862.                  * stream for pseudo-device. */
  2863.     List_Links serviceList;    /* List of all service streams for this
  2864.                  * pseudo-device. */
  2865.     int (*openProc)();        /* Open service procedure */
  2866.     int (*readProc)();        /* Read service procedure */
  2867.     int (*writeProc)();        /* Write service procedure */
  2868.     int (*ioctlProc)();        /* Ioctl service procedure */
  2869.     int (*closeProc)();        /* Close service procedure */
  2870. } Server;
  2871. d106 21
  2872. d128 4
  2873. a131 9
  2874.  * The structure below describes the format of requests in the write
  2875.  * buffer of an ServiceStream.  The kernel queues up requests for us by
  2876.  * appending them to this buffer.  In order to simplify the handling
  2877.  * of requests with a large amount of data, the kernel may break a
  2878.  * (write) request into smaller requests that each fit entirely in
  2879.  * the write buffer.  The MAX_BYTES constant defines this upper limit
  2880.  * on the request data size.  Also remember that writes are asynchronous
  2881.  * so this request buffer size limits the number of writes that can
  2882.  * be done before a context switch to the tty server process is required.
  2883. d133 4
  2884. a137 1
  2885. #define MAX_BYTES    2048
  2886. a138 7
  2887. typedef struct {
  2888.     Pdev_Request hdr;
  2889.     union {
  2890.     int        i;
  2891.     char        chars[MAX_BYTES];
  2892.     } data;
  2893. } Request;
  2894. d141 2
  2895. a142 1
  2896.  * REQUEST_BUF_SIZE     The size of the buffer containing requests
  2897. d145 3
  2898. a147 1
  2899. #define REQUEST_BUF_SIZE    sizeof(Request)
  2900. a149 13
  2901.  * The structure below describes the format of reply messages returned
  2902.  * to the client.
  2903.  */
  2904.  
  2905. typedef struct {
  2906.     Pdev_Reply hdr;
  2907.     union {
  2908.     int        i;
  2909.     char        chars[MAX_BYTES];
  2910.     } data;
  2911. } Reply;
  2912.  
  2913. /*
  2914. d153 1
  2915. d155 1
  2916. a155 6
  2917. extern void    PdevControlRequest();
  2918. extern ReturnStatus    PdevDefaultOpen();
  2919. extern ReturnStatus    PdevDefaultRead();
  2920. extern ReturnStatus    PdevDefaultWrite();
  2921. extern ReturnStatus    PdevDefaultIoctl();
  2922. extern ReturnStatus    PdevDefaultClose();
  2923. d167 3
  2924. a169 10
  2925.  *    The service procedures passed in have the following calling sequence:
  2926.  *    (*openProc)(token, flags, pid, hostID, uid, privatePtr, selectBitsPtr)
  2927.  *        ClientData token;    (Identfies open stream)
  2928.  *        int flags;        (flags to open system call)
  2929.  *        int pid;        (process ID of opening "client" process)
  2930.  *        int hostID;        (Sprite hostID of the client)
  2931.  *        int uid;        (User ID of client process)
  2932.  *        ClientData *privatePtr;    (Settable by open service procedure)
  2933.  *        int *selectBitsPtr;    (Return - initial select state of pdev)
  2934.  *                (FS_READABLE | FS_WRITABLE | FS_EXCEPTION)
  2935. a170 30
  2936.  *    (*closeProc)(private)
  2937.  *        ClientData private;    (Set by open service procedure)
  2938.  *
  2939.  *    (*readProc)(private, offset, familyID, numBytesPtr, buffer, selectBitsPtr)
  2940.  *        ClientData private;    (Set by open service procedure)
  2941.  *        int offset;        (Bytes offset at which to read)
  2942.  *        int familyID;        (Family ID of calling process)
  2943.  *        int *numBytesPtr;    (In/Out - how much to read/was read)
  2944.  *        Address buffer;        (Buffer to fill in with data)
  2945.  *        int *selectBitsPtr;    (Return - select state of pdev)
  2946.  *
  2947.  *    (*writeProc)(private, offset, familyID, numBytesPtr, buffer, selectBitsPtr)
  2948.  *        ClientData private;    (Set by open service procedure)
  2949.  *        int offset;        (Bytes offset at which to read)
  2950.  *        int familyID;        (Family ID of calling process)
  2951.  *        int *numBytesPtr;    (In/Out - how much to write/was written)
  2952.  *        Address buffer;        (Buffer containing data)
  2953.  *        int *selectBitsPtr;    (Return - select state of pdev)
  2954.  *
  2955.  *    (*ioctlProc)(private, command, familyID, inSize, inBuffer, outSizePtr,
  2956.  *            outBuffer, selectBitsPtr)
  2957.  *        ClientData private;    (Set by open service procedure)
  2958.  *        int command;        (IOControl command)
  2959.  *        int familyID;        (Family ID of calling process)
  2960.  *        int inSize;        (Size of inBuffer)
  2961.  *        Address inBuffer;    (Buffer containing input data)
  2962.  *        int *outSizePtr;    (Resutl - size of outBuffer)
  2963.  *        Address outBuffer;    (Buffer containing result data)
  2964.  *        int *selectBitsPtr;    (Return - select state of pdev)
  2965.  *
  2966. d197 1
  2967. a197 1
  2968. Pdev_Open(name, realNamePtr, openProc, closeProc, readProc, writeProc, ioctlProc)
  2969. d207 11
  2970. a217 7
  2971.      /* Any of the service procs can be NULL.  In this case a default
  2972.       * service procedure that ignores the operation will be used */
  2973.     int (*openProc)();        /* Procedure called when client opens pdev */
  2974.     int (*closeProc)();        /* Procedure called when client closes pdev */
  2975.     int (*readProc)();        /* Procedure called when client reads pdev */
  2976.     int (*writeProc)();        /* Procedure called when client writes pdev */
  2977.     int (*ioctlProc)();        /* Procedure called when client ioctls pdev */
  2978. d222 1
  2979. d284 1
  2980. a284 1
  2981.     gotStream:
  2982. d287 8
  2983. a294 6
  2984.     List_Init(&pdevPtr->serviceList);
  2985.  
  2986.     if ((Address)openProc == (Address)NULL) {
  2987.     pdevPtr->openProc = PdevDefaultOpen;
  2988.     } else {
  2989.     pdevPtr->openProc = openProc;
  2990. a295 20
  2991.     if ((Address)closeProc == (Address)NULL) {
  2992.     pdevPtr->closeProc = PdevDefaultClose;
  2993.     } else {
  2994.     pdevPtr->closeProc = closeProc;
  2995.     }
  2996.     if ((Address)readProc == (Address)NULL) {
  2997.     pdevPtr->readProc = PdevDefaultRead;
  2998.     } else {
  2999.     pdevPtr->readProc = readProc;
  3000.     }
  3001.     if ((Address)writeProc == (Address)NULL) {
  3002.     pdevPtr->writeProc = PdevDefaultWrite;
  3003.     } else {
  3004.     pdevPtr->writeProc = writeProc;
  3005.     }
  3006.     if ((Address)ioctlProc == (Address)NULL) {
  3007.     pdevPtr->ioctlProc = PdevDefaultIoctl;
  3008.     } else {
  3009.     pdevPtr->ioctlProc = ioctlProc;
  3010.     }
  3011. d330 2
  3012. a331 2
  3013.     while (!List_IsEmpty(&pdevPtr->serviceList)) {
  3014.     srvPtr = (ServiceStream *) List_First(&pdevPtr->serviceList);
  3015. d341 40
  3016. d450 4
  3017. a453 1
  3018.      * by the kernel to pass client requests to us.
  3019. d458 1
  3020. a458 1
  3021.     List_Insert(&srvPtr->links, LIST_ATFRONT(&pdevPtr->serviceList));
  3022. d461 2
  3023. a462 1
  3024.     srvPtr->requestBuf = (Address) malloc(REQUEST_BUF_SIZE);
  3025. d464 1
  3026. a464 1
  3027.     setBuf.requestBufSize = REQUEST_BUF_SIZE;
  3028. d503 3
  3029. a505 2
  3030.     Request *requestPtr;
  3031.     Reply reply;
  3032. d529 2
  3033. a530 2
  3034.         (Request *)&srvPtr->requestBuf[bufPtrs.requestFirstByte];
  3035.     if (requestPtr->hdr.hdr.magic != PDEV_REQUEST_MAGIC) {
  3036. d532 1
  3037. a532 1
  3038.                 requestPtr->hdr.hdr.magic);
  3039. d534 1
  3040. d536 1
  3041. a536 1
  3042.     switch (requestPtr->hdr.hdr.operation) {
  3043. d538 16
  3044. a553 5
  3045.         status = (*pdevPtr->openProc)(srvPtr->streamID,
  3046.                 requestPtr->hdr.param.open.flags,
  3047.                 requestPtr->hdr.param.open.pid,
  3048.                 requestPtr->hdr.param.open.hostID,
  3049.                 requestPtr->hdr.param.open.uid,
  3050. d558 4
  3051. a561 1
  3052.         status = (*pdevPtr->closeProc)(srvPtr->private);
  3053. d564 31
  3054. a594 8
  3055.         case PDEV_READ:
  3056.         reply.hdr.replySize = requestPtr->hdr.hdr.replySize;
  3057.         status = (*pdevPtr->readProc)(srvPtr->private,
  3058.                 requestPtr->hdr.param.read.offset,
  3059.                 requestPtr->hdr.param.read.familyID,
  3060.                 &reply.hdr.replySize,
  3061.                 &reply.data.chars[0],
  3062.                 &reply.hdr.selectBits);
  3063. d596 3
  3064. d600 17
  3065. a616 9
  3066.         case PDEV_WRITE:
  3067.         reply.hdr.replySize = sizeof(int);
  3068.         reply.data.i = requestPtr->hdr.hdr.requestSize;
  3069.         status = (*pdevPtr->writeProc)(srvPtr->private,
  3070.                 requestPtr->hdr.param.read.offset,
  3071.                 requestPtr->hdr.param.read.familyID,
  3072.                 &reply.data.i,
  3073.                 &requestPtr->data.chars[0],
  3074.                 &reply.hdr.selectBits);
  3075. d619 21
  3076. a639 9
  3077.         case PDEV_IOCTL:
  3078.         status = (*pdevPtr->ioctlProc)(srvPtr->private,
  3079.                  requestPtr->hdr.param.ioctl.command,
  3080.                  requestPtr->hdr.param.ioctl.familyID,
  3081.                  requestPtr->hdr.hdr.requestSize,
  3082.                  &requestPtr->data.chars[0],
  3083.                  &reply.hdr.replySize,
  3084.                  &reply.data.chars[0],
  3085.                  &reply.hdr.selectBits);
  3086. d641 3
  3087. d645 30
  3088. d677 1
  3089. a677 1
  3090.             requestPtr->hdr.hdr.operation);
  3091. d679 3
  3092. d685 1
  3093. a685 1
  3094.     bufPtrs.requestFirstByte += requestPtr->hdr.hdr.messageSize;
  3095. d695 1
  3096. a695 1
  3097.  * PdevCleanup --
  3098. d697 8
  3099. a704 2
  3100.  *    Called when a client has closed in order to
  3101.  *    clean up any associated state.
  3102. d706 67
  3103. d777 1
  3104. a777 1
  3105.  *    .
  3106. d781 7
  3107. d789 33
  3108. a821 9
  3109. static void
  3110. PdevCleanup(srvPtr, status, sendReply)
  3111.     register ServiceStream *srvPtr;    /* Service stream info. */
  3112.     ReturnStatus status;        /* Return status from server */
  3113.     Boolean sendReply;            /* TRUE if we should reply to the
  3114.                      * close request.  This is done in
  3115.                      * normal termination.  FALSE means
  3116.                      * no reply needed, used in error
  3117.                      * recovery */
  3118. d823 15
  3119. a837 2
  3120.     if (sendReply) {
  3121.     ReplyNoData(srvPtr, status, 0);
  3122. d839 218
  3123. a1056 5
  3124.     List_Remove(&srvPtr->links);
  3125.     Fs_EventHandlerDestroy(srvPtr->streamID);
  3126.     close(srvPtr->streamID);
  3127.     free((char *) srvPtr->requestBuf);
  3128.     free((char *) srvPtr);
  3129. d1062 129
  3130. d1262 2
  3131. a1263 1
  3132. PdevDefaultRead(private, offset, familyID, amountReadPtr, buffer, selectBitsPtr)
  3133. d1268 2
  3134. a1269 1
  3135.     Address buffer;        /* Buffer we fill in with data bytes */
  3136. d1343 61
  3137. d1461 1
  3138. a1461 1
  3139.     Reply *replyPtr;        /* Partially completed reply.  The replySize,
  3140. d1464 2
  3141. a1465 3
  3142.     replyPtr->hdr.magic = PDEV_REPLY_MAGIC;
  3143.     replyPtr->hdr.status = status;
  3144.     replyPtr->hdr.replyBuf = &replyPtr->data.chars[0];
  3145. @
  3146.  
  3147.  
  3148. 1.2
  3149. log
  3150. @Updated to new pseudo-device interface
  3151. @
  3152. text
  3153. @d23 1
  3154. a23 1
  3155. static char rcsid[] = "$Header: pdev.c,v 1.1 88/08/26 16:12:17 brent Exp $ SPRITE (Berkeley)";
  3156. d29 1
  3157. a30 2
  3158. #include <errno.h>
  3159. #include <fs.h>
  3160. d514 1
  3161. a514 1
  3162.     if (requestPtr->hdr.magic != PDEV_REQUEST_MAGIC) {
  3163. d516 1
  3164. a516 1
  3165.                 requestPtr->hdr.magic);
  3166. d519 1
  3167. a519 1
  3168.     switch (requestPtr->hdr.operation) {
  3169. d534 1
  3170. a534 1
  3171.         reply.hdr.replySize = requestPtr->hdr.replySize;
  3172. d545 1
  3173. a545 1
  3174.         reply.data.i = requestPtr->hdr.requestSize;
  3175. d558 1
  3176. a558 1
  3177.                  requestPtr->hdr.requestSize,
  3178. d567 1
  3179. a567 1
  3180.             requestPtr->hdr.operation);
  3181. d572 1
  3182. a572 1
  3183.     bufPtrs.requestFirstByte += requestPtr->hdr.messageSize;
  3184. @
  3185.  
  3186.  
  3187. 1.1
  3188. log
  3189. @Initial revision
  3190. @
  3191. text
  3192. @d23 1
  3193. a23 1
  3194. static char rcsid[] = "$Header: ttyDriver.c,v 1.3 88/07/28 17:47:40 ouster Exp $ SPRITE (Berkeley)";
  3195. d99 1
  3196. a99 1
  3197.     Pdev_NewRequest hdr;
  3198. d118 1
  3199. a118 1
  3200.     Pdev_NewReply hdr;
  3201. d791 1
  3202. a791 1
  3203.     Pdev_NewReply reply;
  3204. d799 1
  3205. a799 1
  3206.         sizeof(Pdev_NewReply), (Address) &reply, 0, (Address) NULL);
  3207. d834 1
  3208. a834 1
  3209.         sizeof(Pdev_NewReply), (Address) replyPtr, 0, (Address) NULL);
  3210. @
  3211.